http://mircwiki.rsna.org/api.php?action=feedcontributions&user=Johnperry&feedformat=atomMircWiki - User contributions [en]2024-03-29T05:33:02ZUser contributionsMediaWiki 1.35.5http://mircwiki.rsna.org/index.php?title=The_CTP_DICOM_Filter&diff=10974The CTP DICOM Filter2023-06-25T12:28:44Z<p>Johnperry: </p>
<hr />
<div>The CTP DicomFilter is a pipeline stage that provides preprocessing of DicomObjects, quarantining those which do not meet the conditions of a script program. This article describes the script language. The intended audience for this article is CTP administrators setting up a processing pipeline.<br />
==The Script Language==<br />
The script language interrogates a DICOM object and computes a boolean result that, if <b>true</b>, results in the object being accepted for further processing in the pipeline, and if <b>false</b>, results in the object being quarantined, aborting further processing. <br />
<br />
An expression in the language consists of terms separated by operators and/or parentheses. There are three operators, listed in order of increasing precedence:<br />
*<b>+</b> is logical <b>or</b><br />
*<b>*</b> is logical <b>and</b><br />
*<b>!</b> is unary logical <b>negation</b><br />
<br />
<b>Expression Examples</b>:<br />
*term<br />
*<b>!</b>term<br />
*term + term * term<br />
*term * (term + term) + term * !term<br />
<br />
Terms in the language are either reserved words (<b><tt>true.</tt></b> or <b><tt>false.</tt></b>) (note the periods after the words) or expressions in the form: <br />
<br />
::<tt><b><font color=red>identifier</font>.method("<font color=blue>string</font>")</b></tt><br />
<br />
An identifier is either a DICOM element name as defined in the CTP DICOM Anonymizer (e.g. <tt>SOPInstanceUID</tt>) or a DICOM tag, specified in square brackets (e.g. <tt>[0008,0018]</tt>). No spaces are permitted in identifiers, and tags are required to contain all eight hexadecimal digits identifying the group and element. <br />
<br />
:<em>Note that the identifier syntax supported by the DicomFilter is the same as that supported by the DicomAnonymizer, except that while the DicomAnonymizer supports enclosing element identifiers in either parentheses or square brackets, the DicomFilter supports only square brackets.</em><br />
<br />
An element in the <b>first</b> item dataset of a sequence element may be referenced by connecting identifiers with pairs of colons. There is no limit to the length of the chain of identifiers. All identifiers in the chain except the last must be sequence elements, and the last must not be a sequence element. Examples:<br />
<br />
::<tt>SeqOfUltrasoundRegions::RegionLocationMinY0</tt><br />
::<tt>[0018,6011]::[0018,601A]</tt><br />
::<tt>SeqOfUltrasoundRegions::[0018,601A]</tt><br />
<br />
Elements in private groups can be referenced by their numeric group and element numbers like standard elements, as in <tt>[0029,1140]</tt>. Such elements can also be referenced through their Private Creator elements as in <tt>[0029[XYZ CT HEADER]40]</tt>. This is an example that references an element buried two levels down in a private group:<br />
*<tt>[0029[XYZ CT HEADER]40]::[0017[ALIGNMENT HEADER]42]</tt><br />
In the above example, group 29 exists in the root dataset of the object. In that group, element [0029,0011] contains the text, <tt>XYZ CT HEADER</tt>, thus reserving the block of elements from [0029,1100] through [0029,11FF]. In that block, there is an SQ element [0029,1140]. This is the element referenced by <tt>[0029[XYZ CT HEADER]40]</tt>. The first item dataset of that element contains private group 17, and in that group, there is an element [0017,0010] containing the text, <tt>ALIGNMENT HEADER</tt>, which reserves the block of elements from [0017,1000] through [0017,10FF]. In that block, there is an element [0017,1042]. This is the element referenced by <tt>[0017[ALIGNMENT HEADER]42]</tt>.<br />
<br />
The language supports these methods:<br />
<br />
*<b>equals</b> returns <b>true</b> if the value of the <b>identifier</b> exactly equals the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>equalsIgnoreCase</b> is the case-insensitive version of <b>equals</b>.<br />
<br />
*<b>matches</b> returns <b>true</b> if the value of the <b>identifier</b> matches the regular expression specified in the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>contains</b> returns <b>true</b> if the value of the <b>identifier</b> contains the <b>string</b> argument anywhere within it; otherwise, it returns <b>false</b>.<br />
*<b>containsIgnoreCase</b> is the case-insensitive version of <b>contains</b>.<br />
<br />
*<b>startsWith</b> returns <b>true</b> if the value of the <b>identifier</b> starts with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>startsWithIgnoreCase</b> is the case-insensitive version of <b>startsWith</b>.<br />
<br />
*<b>endsWith</b> returns <b>true</b> if the value of the <b>identifier</b> ends with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>endsWithIgnoreCase</b> is the case-insensitive version of <b>endsWith</b>.<br />
<br />
*<b>isLessThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is less than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>isGreaterThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is greater than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
The value of an identifier is the string value stored in the DICOM object in the element associated with the identifier. If an identifier is missing from the received DICOM object, an empty string is provided.<br />
<br />
The <b>isLessThan</b> and <b>isGreaterThan</b> functions preprocess the value of both the <b>identifier</b> and the <b>string</b> argument by removing all characters except numeric digits and the period. It then converts both to double precision floating point values before doing the requested comparison. If either value fails to parse as a floating point number or integer, the function returns <b>false</b>,<br />
<br />
<b>Comments</b>:<br />
<br />
All text starting with two '/' characters and proceeding to the end of the line is treated as a comment.<br />
<br />
<b>Script Examples</b>:<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY")</b></tt><br />
<br />
Note the unary negation operator, which is necessary to generate <b>true</b> for images which do <b>not</b> contain the string <b>SECONDARY</b>.<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY" or of type "DERIVED". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!(ImageType.contains("SECONDARY") + ImageType.contains("DERIVED"))</b></tt><br />
<br />
Note again the unary negation operator, and also note the parentheses and the logical <b>or</b> operator, all of which combine to generate <b>true</b> only if the type is neither <b>SECONDARY</b> nor <b>DERIVED</b>.<br />
<br />
The same effect could be achieved with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY") * !ImageType.contains("DERIVED")</b></tt><br />
<br />
Note the use of the logical <b>and</b> operator and the way that each term is individually negated.<br />
<br />
Suppose that images containing any non-empty value in the ImageType element are to be rejected. Such images could be filtered out with a script like:<br />
<br />
::<tt><b>ImageType.equals("")</b></tt><br />
<br />
Note that in this case the unary negation operator is not used because if the element is missing or empty, the <b>equals</b> method will generate <b>true</b>, which is the value necessary to pass the object down the pipeline. This script could also be coded using the DICOM group and element numbers like this:<br />
<br />
::<tt><b>[0008,0008].equals("")</b></tt><br />
<br />
Suppose images are to be selected with SliceThickness less than or equal to 3mm. One way to do it would be:<br />
<br />
::<tt><b>!SliceThickness.isGreaterThan("3")</b></tt><br />
<br />
Here is an example with comments:<br />
<br />
<pre><br />
//This is a comment<br />
!PatientName.equals("xyz") //accept anybody but xyz<br />
+ !PatientID.contains("1") //or anybody without a 1 in the PatientID<br />
//+ InstitutionName.containsIgnoreCase("JACKSONVILLE") //note: this line is ignored because it starts with //<br />
//This is another comment<br />
</pre></div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_CTP_DICOM_Filter&diff=8072The CTP DICOM Filter2021-10-15T00:45:32Z<p>Johnperry: /* The Script Language */</p>
<hr />
<div>The CTP DicomFilter is a pipeline stage that provides preprocessing of DicomObjects, quarantining those which do not meet the conditions of a script program. This article describes the script language. The intended audience for this article is CTP administrators setting up a processing pipeline.<br />
==The Script Language==<br />
The script language interrogates a DICOM object and computes a boolean result that, if <b>true</b>, results in the object being accepted for further processing in the pipeline, and if <b>false</b>, results in the object being quarantined, aborting further processing. <br />
<br />
An expression in the language consists of terms separated by operators and/or parentheses. There are three operators, listed in order of increasing precedence:<br />
*<b>+</b> is logical <b>or</b><br />
*<b>*</b> is logical <b>and</b><br />
*<b>!</b> is unary logical <b>negation</b><br />
<br />
<b>Expression Examples</b>:<br />
*term<br />
*<b>!</b>term<br />
*term + term * term<br />
*term * (term + term) + term * !term<br />
<br />
Terms in the language are either reserved words (<b><tt>true.</tt></b> or <b><tt>false.</tt></b>) (note the periods after the words) or expressions in the form: <br />
<br />
::<tt><b><font color=red>identifier</font>.method("<font color=blue>string</font>")</b></tt><br />
<br />
An identifier is either a DICOM element name as defined in the CTP DICOM Anonymizer (e.g. <tt>SOPInstanceUID</tt>) or a DICOM tag, specified in square brackets (e.g. <tt>[0008,0018]</tt>). No spaces are permitted in identifiers, and tags are required to contain all eight hexadecimal digits identifying the group and element. <br />
<br />
:<em>Note that the identifier syntax supported by the DicomFilter is the same as that supported by the DicomAnonymizer, except that while the DicomAnonymizer supports enclosing element identifiers in either parentheses or square brackets, the DicomFilter supports only square brackets.</em><br />
<br />
An element in the <b>first</b> item dataset of a sequence element may be referenced by connecting identifiers with pairs of colons. There is no limit to the length of the chain of identifiers. All identifiers in the chain except the last must be sequence elements, and the last must not be a sequence element. Examples:<br />
<br />
::<tt>SeqOfUltrasoundRegions::RegionLocationMinY0</tt><br />
::<tt>[0018,6011]::[0018,601A]</tt><br />
::<tt>SeqOfUltrasoundRegions::[0018,601A]</tt><br />
<br />
Elements in private groups can be referenced by their numeric group and element numbers like standard elements, as in <tt>[0029,1140]</tt>. Such elements can also be referenced through their Private Creator elements as in <tt>[0029[XYZ CT HEADER]40]</tt>. This is an example that references an element buried two levels down in a private group:<br />
*<tt>[0029[XYZ CT HEADER]40]::[0017[ALIGNMENT HEADER]42]</tt><br />
In the above example, group 29 exists in the root dataset of the object. In that group, element [0029,0011] contains the text, <tt>XYZ CT HEADER</tt>, thus reserving the block of elements from [0029,1100] through [0029,11FF]. In that block, there is an SQ element [0029,1140]. This is the element referenced by <tt>[0029[XYZ CT HEADER]40]</tt>. The first item dataset of that element contains private group 17, and in that group, there is an element [0017,0010] containing the text, <tt>ALIGNMENT HEADER</tt>, which reserves the block of elements from [0017,1000] through [0017,10FF]. In that block, there is an element [0017,1042]. This is the element referenced by <tt>[0017[ALIGNMENT HEADER]42]</tt>.<br />
<br />
The language supports these methods:<br />
<br />
*<b>equals</b> returns <b>true</b> if the value of the <b>identifier</b> exactly equals the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>equalsIgnoreCase</b> is the case-insensitive version of <b>equals</b>.<br />
<br />
*<b>matches</b> returns <b>true</b> if the value of the <b>identifier</b> matches the regular expression specified in the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>contains</b> returns <b>true</b> if the value of the <b>identifier</b> contains the the <b>string</b> argument anywhere within it; otherwise, it returns <b>false</b>.<br />
*<b>containsIgnoreCase</b> is the case-insensitive version of <b>contains</b>.<br />
<br />
*<b>startsWith</b> returns <b>true</b> if the value of the <b>identifier</b> starts with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>startsWithIgnoreCase</b> is the case-insensitive version of <b>startsWith</b>.<br />
<br />
*<b>endsWith</b> returns <b>true</b> if the value of the <b>identifier</b> ends with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>endsWithIgnoreCase</b> is the case-insensitive version of <b>endsWith</b>.<br />
<br />
*<b>isLessThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is less than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>isGreaterThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is greater than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
The value of an identifier is the string value stored in the DICOM object in the element associated with the identifier. If an identifier is missing from the received DICOM object, an empty string is provided.<br />
<br />
The <b>isLessThan</b> and <b>isGreaterThan</b> functions preprocess the value of both the <b>identifier</b> and the <b>string</b> argument by removing all characters except numeric digits and the period. It then converts both to double precision floating point values before doing the requested comparison. If either value fails to parse as a floating point number or integer, the function returns <b>false</b>,<br />
<br />
<b>Comments</b>:<br />
<br />
All text starting with two '/' characters and proceeding to the end of the line is treated as a comment.<br />
<br />
<b>Script Examples</b>:<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY")</b></tt><br />
<br />
Note the unary negation operator, which is necessary to generate <b>true</b> for images which do <b>not</b> contain the string <b>SECONDARY</b>.<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY" or of type "DERIVED". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!(ImageType.contains("SECONDARY") + ImageType.contains("DERIVED"))</b></tt><br />
<br />
Note again the unary negation operator, and also note the parentheses and the logical <b>or</b> operator, all of which combine to generate <b>true</b> only if the type is neither <b>SECONDARY</b> nor <b>DERIVED</b>.<br />
<br />
The same effect could be achieved with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY") * !ImageType.contains("DERIVED")</b></tt><br />
<br />
Note the use of the logical <b>and</b> operator and the way that each term is individually negated.<br />
<br />
Suppose that images containing any non-empty value in the ImageType element are to be rejected. Such images could be filtered out with a script like:<br />
<br />
::<tt><b>ImageType.equals("")</b></tt><br />
<br />
Note that in this case the unary negation operator is not used because if the element is missing or empty, the <b>equals</b> method will generate <b>true</b>, which is the value necessary to pass the object down the pipeline. This script could also be coded using the DICOM group and element numbers like this:<br />
<br />
::<tt><b>[0008,0008].equals("")</b></tt><br />
<br />
Suppose images are to be selected with SliceThickness less than or equal to 3mm. One way to do it would be:<br />
<br />
::<tt><b>!SliceThickness.isGreaterThan("3")</b></tt><br />
<br />
Here is an example with comments:<br />
<br />
<pre><br />
//This is a comment<br />
!PatientName.equals("xyz") //accept anybody but xyz<br />
+ !PatientID.contains("1") //or anybody without a 1 in the PatientID<br />
//+ InstitutionName.containsIgnoreCase("JACKSONVILLE") //note: this line is ignored because it starts with //<br />
//This is another comment<br />
</pre></div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_CTP_DICOM_Filter&diff=8071The CTP DICOM Filter2021-10-15T00:43:11Z<p>Johnperry: /* The Script Language */</p>
<hr />
<div>The CTP DicomFilter is a pipeline stage that provides preprocessing of DicomObjects, quarantining those which do not meet the conditions of a script program. This article describes the script language. The intended audience for this article is CTP administrators setting up a processing pipeline.<br />
==The Script Language==<br />
The script language interrogates a DICOM object and computes a boolean result that, if <b>true</b>, results in the object being accepted for further processing in the pipeline, and if <b>false</b>, results in the object being quarantined, aborting further processing. <br />
<br />
An expression in the language consists of terms separated by operators and/or parentheses. There are three operators, listed in order of increasing precedence:<br />
*<b>+</b> is logical <b>or</b><br />
*<b>*</b> is logical <b>and</b><br />
*<b>!</b> is unary logical <b>negation</b><br />
<br />
<b>Expression Examples</b>:<br />
*term<br />
*<b>!</b>term<br />
*term + term * term<br />
*term * (term + term) + term * !term<br />
<br />
Terms in the language are either reserved words (<b><tt>true.</tt></b> or <b><tt>false.</tt></b>) (note the periods after the words) or expressions in the form: <br />
<br />
::<tt><b><font color=red>identifier</font>.method("<font color=blue>string</font>")</b></tt><br />
<br />
An identifier is either a DICOM element name as defined in the CTP DICOM Anonymizer (e.g. <tt>SOPInstanceUID</tt>) or a DICOM tag, specified in square brackets (e.g. <tt>[0008,0018]</tt>). No spaces are permitted in identifiers, and tags are required to contain all eight hexadecimal digits identifying the group and element. <br />
<br />
:<em>Note that the identifier syntax supported by the DicomFilter is the same as that supported by the DicomAnonymizer, except that while the DicomAnonymizer supports enclosing element identifiers in either parentheses or square brackets, the DicomFilter supports only square brackets.</em><br />
<br />
An element in the <b>first</b> item dataset of a sequence element may be referenced by connecting identifiers with pairs of colons. There is no limit to the length of the chain of identifiers. All identifiers in the chain except the last must be sequence elements, and the last must not be a sequence element. Examples:<br />
<br />
::<tt>SeqOfUltrasoundRegions::RegionLocationMinY0</tt><br />
::<tt>[0018,6011]::[0018,601A]</tt><br />
::<tt>SeqOfUltrasoundRegions::[0018,601A]</tt><br />
<br />
Elements in private groups can be referenced by their numeric group and element numbers like standard elements, as in <tt>[0029,1140]</tt>. Such elements can also be referenced through their Private Creator elements as in <tt>[0029[XYZ CT HEADER]40]</tt>. This is an example that references an element buried two levels down in a private group:<br />
*<tt>[0029[XYZ CT HEADER]40]::[0017[ALIGNMENT HEADER]42]</tt><br />
In the above example, group 29 exists in the root dataset of the object. In that group, element [0029,0011] contains the text, <tt>XYZ CT HEADER</tt>, thus reserving the block of elements from [0029,1100] through [0029,11FF]. In that block, there is an SQ element [0029,1140]. This is the element referenced by <tt>[0029[XYZ CT HEADER]40]</tt>. The first item dataset of that element contains private group 17, and in that group, there is an element [0017,0010] containing the text, <tt>ALIGNMENT HEADER</tt>, which reserves the block of elements from [0017,1000] through [0017,10FF]. In that block, there is an element [0017,1042]. This is the element referenced by <tt>[0017[ALIGNMENT HEADER]42]</tt>.<br />
<br />
The language supports these methods:<br />
<br />
*<b>equals</b> returns <b>true</b> if the value of the <b>identifier</b> exactly equals the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>equalsIgnoreCase</b> is the case-insensitive version of <b>equals</b>.<br />
<br />
*<b>matches</b> returns <b>true</b> if the value of the <b>identifier</b> matches the regular expression specified in the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>contains</b> returns <b>true</b> if the value of the <b>identifier</b> contains the the <b>string</b> argument anywhere within it; otherwise, it returns <b>false</b>.<br />
*<b>containsIgnoreCase</b> is the case-insensitive version of <b>contains</b>.<br />
<br />
*<b>startsWith</b> returns <b>true</b> if the value of the <b>identifier</b> starts with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>startsWithIgnoreCase</b> is the case-insensitive version of <b>startsWith</b>.<br />
<br />
*<b>endsWith</b> returns <b>true</b> if the value of the <b>identifier</b> ends with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>endsWithIgnoreCase</b> is the case-insensitive version of <b>endsWith</b>.<br />
<br />
*<b>isLessThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is less than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>isGreaterThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is greater than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
The value of an identifier is the string value stored in the DICOM object in the element associated with the identifier. If an identifier is missing from the received DICOM object, an empty string is provided.<br />
<br />
The <b>isLessThan</b> and <b>isGreaterThan</b> functions preprocess the value of both the <b>identifier</b> and the <b>string</b> argument by removing all characters except numeric digits and the period. It then converts both to double precision floating point values before doing the requested comparison.<br />
<br />
<b>Comments</b>:<br />
<br />
All text starting with two '/' characters and proceeding to the end of the line is treated as a comment.<br />
<br />
<b>Script Examples</b>:<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY")</b></tt><br />
<br />
Note the unary negation operator, which is necessary to generate <b>true</b> for images which do <b>not</b> contain the string <b>SECONDARY</b>.<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY" or of type "DERIVED". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!(ImageType.contains("SECONDARY") + ImageType.contains("DERIVED"))</b></tt><br />
<br />
Note again the unary negation operator, and also note the parentheses and the logical <b>or</b> operator, all of which combine to generate <b>true</b> only if the type is neither <b>SECONDARY</b> nor <b>DERIVED</b>.<br />
<br />
The same effect could be achieved with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY") * !ImageType.contains("DERIVED")</b></tt><br />
<br />
Note the use of the logical <b>and</b> operator and the way that each term is individually negated.<br />
<br />
Suppose that images containing any non-empty value in the ImageType element are to be rejected. Such images could be filtered out with a script like:<br />
<br />
::<tt><b>ImageType.equals("")</b></tt><br />
<br />
Note that in this case the unary negation operator is not used because if the element is missing or empty, the <b>equals</b> method will generate <b>true</b>, which is the value necessary to pass the object down the pipeline. This script could also be coded using the DICOM group and element numbers like this:<br />
<br />
::<tt><b>[0008,0008].equals("")</b></tt><br />
<br />
Suppose images are to be selected with SliceThickness less than or equal to 3mm. One way to do it would be:<br />
<br />
::<tt><b>!SliceThickness.isGreaterThan("3")</b></tt><br />
<br />
Here is an example with comments:<br />
<br />
<pre><br />
//This is a comment<br />
!PatientName.equals("xyz") //accept anybody but xyz<br />
+ !PatientID.contains("1") //or anybody without a 1 in the PatientID<br />
//+ InstitutionName.containsIgnoreCase("JACKSONVILLE") //note: this line is ignored because it starts with //<br />
//This is another comment<br />
</pre></div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_CTP_DICOM_Filter&diff=8070The CTP DICOM Filter2021-10-15T00:36:18Z<p>Johnperry: /* The Script Language */</p>
<hr />
<div>The CTP DicomFilter is a pipeline stage that provides preprocessing of DicomObjects, quarantining those which do not meet the conditions of a script program. This article describes the script language. The intended audience for this article is CTP administrators setting up a processing pipeline.<br />
==The Script Language==<br />
The script language interrogates a DICOM object and computes a boolean result that, if <b>true</b>, results in the object being accepted for further processing in the pipeline, and if <b>false</b>, results in the object being quarantined, aborting further processing. <br />
<br />
An expression in the language consists of terms separated by operators and/or parentheses. There are three operators, listed in order of increasing precedence:<br />
*<b>+</b> is logical <b>or</b><br />
*<b>*</b> is logical <b>and</b><br />
*<b>!</b> is unary logical <b>negation</b><br />
<br />
<b>Expression Examples</b>:<br />
*term<br />
*<b>!</b>term<br />
*term + term * term<br />
*term * (term + term) + term * !term<br />
<br />
Terms in the language are either reserved words (<b><tt>true.</tt></b> or <b><tt>false.</tt></b>) (note the periods after the words) or expressions in the form: <br />
<br />
::<tt><b><font color=red>identifier</font>.method("<font color=blue>string</font>")</b></tt><br />
<br />
An identifier is either a DICOM element name as defined in the CTP DICOM Anonymizer (e.g. <tt>SOPInstanceUID</tt>) or a DICOM tag, specified in square brackets (e.g. <tt>[0008,0018]</tt>). No spaces are permitted in identifiers, and tags are required to contain all eight hexadecimal digits identifying the group and element. <br />
<br />
:<em>Note that the identifier syntax supported by the DicomFilter is the same as that supported by the DicomAnonymizer, except that while the DicomAnonymizer supports enclosing element identifiers in either parentheses or square brackets, the DicomFilter supports only square brackets.</em><br />
<br />
An element in the <b>first</b> item dataset of a sequence element may be referenced by connecting identifiers with pairs of colons. There is no limit to the length of the chain of identifiers. All identifiers in the chain except the last must be sequence elements, and the last must not be a sequence element. Examples:<br />
<br />
::<tt>SeqOfUltrasoundRegions::RegionLocationMinY0</tt><br />
::<tt>[0018,6011]::[0018,601A]</tt><br />
::<tt>SeqOfUltrasoundRegions::[0018,601A]</tt><br />
<br />
Elements in private groups can be referenced by their numeric group and element numbers like standard elements, as in <tt>[0029,1140]</tt>. Such elements can also be referenced through their Private Creator elements as in <tt>[0029[XYZ CT HEADER]40]</tt>. This is an example that references an element buried two levels down in a private group:<br />
*<tt>[0029[XYZ CT HEADER]40]::[0017[ALIGNMENT HEADER]42]</tt><br />
In the above example, group 29 exists in the root dataset of the object. In that group, element [0029,0011] contains the text, <tt>XYZ CT HEADER</tt>, thus reserving the block of elements from [0029,1100] through [0029,11FF]. In that block, there is an SQ element [0029,1140]. This is the element referenced by <tt>[0029[XYZ CT HEADER]40]</tt>. The first item dataset of that element contains private group 17, and in that group, there is an element [0017,0010] containing the text, <tt>ALIGNMENT HEADER</tt>, which reserves the block of elements from [0017,1000] through [0017,10FF]. In that block, there is an element [0017,1042]. This is the element referenced by <tt>[0017[ALIGNMENT HEADER]42]</tt>.<br />
<br />
The language supports these methods:<br />
<br />
*<b>equals</b> returns <b>true</b> if the value of the <b>identifier</b> exactly equals the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>equalsIgnoreCase</b> is the case-insensitive version of <b>equals</b>.<br />
<br />
*<b>matches</b> returns <b>true</b> if the value of the <b>identifier</b> matches the regular expression specified in the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>contains</b> returns <b>true</b> if the value of the <b>identifier</b> contains the the <b>string</b> argument anywhere within it; otherwise, it returns <b>false</b>.<br />
*<b>containsIgnoreCase</b> is the case-insensitive version of <b>contains</b>.<br />
<br />
*<b>startsWith</b> returns <b>true</b> if the value of the <b>identifier</b> starts with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>startsWithIgnoreCase</b> is the case-insensitive version of <b>startsWith</b>.<br />
<br />
*<b>endsWith</b> returns <b>true</b> if the value of the <b>identifier</b> ends with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>endsWithIgnoreCase</b> is the case-insensitive version of <b>endsWith</b>.<br />
<br />
*<b>isLessThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is less than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>isGreaterThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is greater than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
The value of an identifier is the string value stored in the DICOM object in the element associated with the identifier. If an identifier is missing from the received DICOM object, an empty string is provided.<br />
<br />
The <b>isLessThan</b> and <b>isGreaterThan</b> functions preprocess the value of both the <b>identifier</b> and the <b>string</b> argument by removing all characters except numeric digits and the period. It then converts both to double precision floating point values before doing the requested comparison.<br />
<br />
<b>Comments</b>:<br />
<br />
All text starting with two '/' characters and proceeding to the end of the line is treated as a comment.<br />
<br />
<b>Script Examples</b>:<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY")</b></tt><br />
<br />
Note the unary negation operator, which is necessary to generate <b>true</b> for images which do <b>not</b> contain the string <b>SECONDARY</b>.<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY" or of type "DERIVED". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!(ImageType.contains("SECONDARY") + ImageType.contains("DERIVED"))</b></tt><br />
<br />
Note again the unary negation operator, and also note the parentheses and the logical <b>or</b> operator, all of which combine to generate <b>true</b> only if the type is neither <b>SECONDARY</b> nor <b>DERIVED</b>.<br />
<br />
The same effect could be achieved with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY") * !ImageType.contains("DERIVED")</b></tt><br />
<br />
Note the use of the logical <b>and</b> operator and the way that each term is individually negated.<br />
<br />
Finally, suppose that images containing any non-empty value in the ImageType element are to be rejected. Such images could be filtered out with a script like:<br />
<br />
::<tt><b>ImageType.equals("")</b></tt><br />
<br />
Note that in this case the unary negation operator is not used because if the element is missing or empty, the <b>equals</b> method will generate <b>true</b>, which is the value necessary to pass the object down the pipeline. This script could also be coded using the DICOM group and element numbers like this:<br />
<br />
::<tt><b>[0008,0008].equals("")</b></tt><br />
<br />
Here is an example with comments:<br />
<br />
<pre><br />
//This is a comment<br />
!PatientName.equals("xyz") //accept anybody but xyz<br />
+ !PatientID.contains("1") //or anybody without a 1 in the PatientID<br />
//+ InstitutionName.containsIgnoreCase("JACKSONVILLE") //note: this line is ignored because it starts with //<br />
//This is another comment<br />
</pre></div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_CTP_DICOM_Filter&diff=8069The CTP DICOM Filter2021-10-15T00:35:21Z<p>Johnperry: /* The Script Language */</p>
<hr />
<div>The CTP DicomFilter is a pipeline stage that provides preprocessing of DicomObjects, quarantining those which do not meet the conditions of a script program. This article describes the script language. The intended audience for this article is CTP administrators setting up a processing pipeline.<br />
==The Script Language==<br />
The script language interrogates a DICOM object and computes a boolean result that, if <b>true</b>, results in the object being accepted for further processing in the pipeline, and if <b>false</b>, results in the object being quarantined, aborting further processing. <br />
<br />
An expression in the language consists of terms separated by operators and/or parentheses. There are three operators, listed in order of increasing precedence:<br />
*<b>+</b> is logical <b>or</b><br />
*<b>*</b> is logical <b>and</b><br />
*<b>!</b> is unary logical <b>negation</b><br />
<br />
<b>Expression Examples</b>:<br />
*term<br />
*<b>!</b>term<br />
*term + term * term<br />
*term * (term + term) + term * !term<br />
<br />
Terms in the language are either reserved words (<b><tt>true.</tt></b> or <b><tt>false.</tt></b>) (note the periods after the words) or expressions in the form: <br />
<br />
::<tt><b><font color=red>identifier</font>.method("<font color=blue>string</font>")</b></tt><br />
<br />
An identifier is either a DICOM element name as defined in the CTP DICOM Anonymizer (e.g. <tt>SOPInstanceUID</tt>) or a DICOM tag, specified in square brackets (e.g. <tt>[0008,0018]</tt>). No spaces are permitted in identifiers, and tags are required to contain all eight hexadecimal digits identifying the group and element. <br />
<br />
:<em>Note that the identifier syntax supported by the DicomFilter is the same as that supported by the DicomAnonymizer, except that while the DicomAnonymizer supports enclosing element identifiers in either parentheses or square brackets, the DicomFilter supports only square brackets.</em><br />
<br />
An element in the <b>first</b> item dataset of a sequence element may be referenced by connecting identifiers with pairs of colons. There is no limit to the length of the chain of identifiers. All identifiers in the chain except the last must be sequence elements, and the last must not be a sequence element. Examples:<br />
<br />
::<tt>SeqOfUltrasoundRegions::RegionLocationMinY0</tt><br />
::<tt>[0018,6011]::[0018,601A]</tt><br />
::<tt>SeqOfUltrasoundRegions::[0018,601A]</tt><br />
<br />
Elements in private groups can be referenced by their numeric group and element numbers like standard elements, as in <tt>[0029,1140]</tt>. Such elements can also be referenced through their Private Creator elements as in <tt>[0029[XYZ CT HEADER]40]</tt>. This is an example that references an element buried two levels down in a private group:<br />
*<tt>[0029[XYZ CT HEADER]40]::[0017[ALIGNMENT HEADER]42]</tt><br />
In the above example, group 29 exists in the root dataset of the object. In that group, element [0029,0011] contains the text, <tt>XYZ CT HEADER</tt>, thus reserving the block of elements from [0029,1100] through [0029,11FF]. In that block, there is an SQ element [0029,1140]. This is the element referenced by <tt>[0029[XYZ CT HEADER]40]</tt>. The first item dataset of that element contains private group 17, and in that group, there is an element [0017,0010] containing the text, <tt>ALIGNMENT HEADER</tt>, which reserves the block of elements from [0017,1000] through [0017,10FF]. In that block, there is an element [0017,1042]. This is the element referenced by <tt>[0017[ALIGNMENT HEADER]42]</tt>.<br />
<br />
The language supports these methods:<br />
<br />
*<b>equals</b> returns <b>true</b> if the value of the <b>identifier</b> exactly equals the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>equalsIgnoreCase</b> is the case-insensitive version of <b>equals</b>.<br />
<br />
*<b>matches</b> returns <b>true</b> if the value of the <b>identifier</b> matches the regular expression specified in the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
*<b>contains</b> returns <b>true</b> if the value of the <b>identifier</b> contains the the <b>string</b> argument anywhere within it; otherwise, it returns <b>false</b>.<br />
*<b>containsIgnoreCase</b> is the case-insensitive version of <b>contains</b>.<br />
<br />
*<b>startsWith</b> returns <b>true</b> if the value of the <b>identifier</b> starts with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>startsWithIgnoreCase</b> is the case-insensitive version of <b>startsWith</b>.<br />
<br />
*<b>endsWith</b> returns <b>true</b> if the value of the <b>identifier</b> ends with the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
*<b>endsWithIgnoreCase</b> is the case-insensitive version of <b>endsWith</b>.<br />
<br />
*<b>isLessThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is less than the numeric value of the <b>string</b> argument; otherwise, it <br />
returns <b>false</b>.<br />
<br />
*<b>isGreaterThan</b> returns <b>true</b> if the numeric value of the <b>identifier</b> is greater than the numeric value of the <b>string</b> argument; otherwise, it returns <b>false</b>.<br />
<br />
The value of an identifier is the string value stored in the DICOM object in the element associated with the identifier. If an identifier is missing from the received DICOM object, an empty string is provided.<br />
<br />
The <b>isLessThan</b> and <b>isGreaterThan</b> functions preprocess the value of both the <b>identifier</b> and the <b>string</b> argument by removing all characters except numeric digits and the period. It then converts both to double precision floating point values before doing the requested comparison.<br />
<br />
<b>Comments</b>:<br />
<br />
All text starting with two '/' characters and proceeding to the end of the line is treated as a comment.<br />
<br />
<b>Script Examples</b>:<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY")</b></tt><br />
<br />
Note the unary negation operator, which is necessary to generate <b>true</b> for images which do <b>not</b> contain the string <b>SECONDARY</b>.<br />
<br />
Suppose that images are to be rejected if they are of type "SECONDARY" or of type "DERIVED". Such images could be filtered out of the pipeline with a script like:<br />
<br />
::<tt><b>!(ImageType.contains("SECONDARY") + ImageType.contains("DERIVED"))</b></tt><br />
<br />
Note again the unary negation operator, and also note the parentheses and the logical <b>or</b> operator, all of which combine to generate <b>true</b> only if the type is neither <b>SECONDARY</b> nor <b>DERIVED</b>.<br />
<br />
The same effect could be achieved with a script like:<br />
<br />
::<tt><b>!ImageType.contains("SECONDARY") * !ImageType.contains("DERIVED")</b></tt><br />
<br />
Note the use of the logical <b>and</b> operator and the way that each term is individually negated.<br />
<br />
Finally, suppose that images containing any non-empty value in the ImageType element are to be rejected. Such images could be filtered out with a script like:<br />
<br />
::<tt><b>ImageType.equals("")</b></tt><br />
<br />
Note that in this case the unary negation operator is not used because if the element is missing or empty, the <b>equals</b> method will generate <b>true</b>, which is the value necessary to pass the object down the pipeline. This script could also be coded using the DICOM group and element numbers like this:<br />
<br />
::<tt><b>[0008,0008].equals("")</b></tt><br />
<br />
Here is an example with comments:<br />
<br />
<pre><br />
//This is a comment<br />
!PatientName.equals("xyz") //accept anybody but xyz<br />
+ !PatientID.contains("1") //or anybody without a 1 in the PatientID<br />
//+ InstitutionName.containsIgnoreCase("JACKSONVILLE") //note: this line is ignored because it starts with //<br />
//This is another comment<br />
</pre></div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8068MIRC CTP2021-06-25T12:20:48Z<p>Johnperry: /* DirectoryStorageService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomECGProcessor=====<br />
The DicomECGProcessor is a processor stage that modifies DicomObjects containing ECG waveforms. If the DicomObject does not contain an image, the stage renders the ECG waveforms into a DICOM native format image and inserts the image into the DicomObject. It passes all other objects without modification. This stage can be used in combination with the PictureStorageService to obtain images of the waveforms for use in non-DICOM applications. The configuration element for the DicomECGProcessor is:<br />
<pre><br />
<DicomECGProcessor <br />
name="DicomECGProcessor "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomECGProcessor "<br />
root="root-directory" <br />
format="portrait|landscape" <br />
synthesizeMissingLeads="yes|no" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomECGProcessor for temporary storage.<br />
*<b>format</b> specifies whether to render the waveforms on a portrait page or a landscape page. Values are "portrait" or "landscape". The default is "portrait".<br />
*<b>synthesizeMissingLeads</b> specifies whether to synthesize missing any leads )III, AVR, AVL, and AVF) from the other waveforms in the DicomObject. The default is "no".<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags or keywords. Keywords must be enclosed in braces. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows tags for the structure above using DICOM keywords: <b><tt>{PatientID}/{AccessionNumber}/{StudyInstanceUID}</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# This example shows tags for the structure above using DICOM keywords: <b><tt>{PatientID}/{StudyInstanceUID} - {AccessionNumber}</tt></b>.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PictureStorageService=====<br />
The PictureStorageService stores images extracted from DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. The operation of this stage is similar to that of the DirectoryStorageService except that it only operates on DicomObjects and it stores only the extracted picture, with no accompanying information.<br />
<br />
<pre><br />
<PictureStorageService<br />
name="PictureStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
format="jpeg|png"<br />
maxWidth="1024"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PictureStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>format</b> specifies the format of the stored picture. Values are "jpeg" and "png". The default is "jpeg".<br />
*<b>maxWidth</b> specifies the maximum width allowed for the stored picture. The default is 1024. Pictures wider than maxWidth are scaled down to maxWidth. Pictures smaller than maxWidth are stored at their native size.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name unless it is overridden by the filenameTag attribute.<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8067MIRC CTP2020-11-25T17:40:20Z<p>Johnperry: /* PictureStorageService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomECGProcessor=====<br />
The DicomECGProcessor is a processor stage that modifies DicomObjects containing ECG waveforms. If the DicomObject does not contain an image, the stage renders the ECG waveforms into a DICOM native format image and inserts the image into the DicomObject. It passes all other objects without modification. This stage can be used in combination with the PictureStorageService to obtain images of the waveforms for use in non-DICOM applications. The configuration element for the DicomECGProcessor is:<br />
<pre><br />
<DicomECGProcessor <br />
name="DicomECGProcessor "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomECGProcessor "<br />
root="root-directory" <br />
format="portrait|landscape" <br />
synthesizeMissingLeads="yes|no" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomECGProcessor for temporary storage.<br />
*<b>format</b> specifies whether to render the waveforms on a portrait page or a landscape page. Values are "portrait" or "landscape". The default is "portrait".<br />
*<b>synthesizeMissingLeads</b> specifies whether to synthesize missing any leads )III, AVR, AVL, and AVF) from the other waveforms in the DicomObject. The default is "no".<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PictureStorageService=====<br />
The PictureStorageService stores images extracted from DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. The operation of this stage is similar to that of the DirectoryStorageService except that it only operates on DicomObjects and it stores only the extracted picture, with no accompanying information.<br />
<br />
<pre><br />
<PictureStorageService<br />
name="PictureStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
format="jpeg|png"<br />
maxWidth="1024"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PictureStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>format</b> specifies the format of the stored picture. Values are "jpeg" and "png". The default is "jpeg".<br />
*<b>maxWidth</b> specifies the maximum width allowed for the stored picture. The default is 1024. Pictures wider than maxWidth are scaled down to maxWidth. Pictures smaller than maxWidth are stored at their native size.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name unless it is overridden by the filenameTag attribute.<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8066MIRC CTP2020-11-25T17:39:10Z<p>Johnperry: /* DicomECGProcessor */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomECGProcessor=====<br />
The DicomECGProcessor is a processor stage that modifies DicomObjects containing ECG waveforms. If the DicomObject does not contain an image, the stage renders the ECG waveforms into a DICOM native format image and inserts the image into the DicomObject. It passes all other objects without modification. This stage can be used in combination with the PictureStorageService to obtain images of the waveforms for use in non-DICOM applications. The configuration element for the DicomECGProcessor is:<br />
<pre><br />
<DicomECGProcessor <br />
name="DicomECGProcessor "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomECGProcessor "<br />
root="root-directory" <br />
format="portrait|landscape" <br />
synthesizeMissingLeads="yes|no" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomECGProcessor for temporary storage.<br />
*<b>format</b> specifies whether to render the waveforms on a portrait page or a landscape page. Values are "portrait" or "landscape". The default is "portrait".<br />
*<b>synthesizeMissingLeads</b> specifies whether to synthesize missing any leads )III, AVR, AVL, and AVF) from the other waveforms in the DicomObject. The default is "no".<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PictureStorageService=====<br />
The PictureStorageService stores images extracted from DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. The operation of this stage is similar to that of the DirectoryStorageService except that it only operates on DicomObjects and it stores only the extracted picture, with no accompanying information.<br />
<br />
<pre><br />
<PictureStorageService<br />
name="PictureStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
format="jpeg|png"<br />
maxWidth="1024"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PictureStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>format</b> specifies the format of the stored picture. Values are "jpeg" and "png". The default is "jpeg".<br />
*<b>maxWidth</b> specifies the maximum width allowed for the stored picture. The default is 1024. Pictures wider than maxWidth are scaled down to masxWidth. Pictures smaller than maxWidth are stored at their native size.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name unless it is overridden by the filenameTag attribute.<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8065MIRC CTP2020-11-25T17:38:01Z<p>Johnperry: /* DicomPhotometricInterpretationConverter */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomECGProcessor=====<br />
The DicomECGProcessor is a processor stage that modifies DicomObjects containing ECG waveforms. If the DicomObject does not contain an image, the stage renders the ECG waveforms into a DICOM native format image and inserts the image into the DicomObject. It passes all other objects without modification. This stage can be used in combination with the PictureStorageService to obtain images of the waveforms for use in non-DICOM applications. The configuration element for the DicomECGProcessor is:<br />
<pre><br />
<DicomECGProcessor <br />
name="DicomECGProcessor "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomECGProcessor "<br />
root="root-directory" <br />
format="portrait|landscape" <br />
synthesizeMissingLeads="yes|no" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>format</b> specifies whether to render the waveforms on a portrait page or a landscape page. Values are "portrait" or "landscape". The default is "portrait".<br />
*<b>synthesizeMissingLeads</b> specifies whether to synthesize missing any leads )III, AVR, AVL, and AVF) from the other waveforms in the DicomObject. The default is "no".<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PictureStorageService=====<br />
The PictureStorageService stores images extracted from DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. The operation of this stage is similar to that of the DirectoryStorageService except that it only operates on DicomObjects and it stores only the extracted picture, with no accompanying information.<br />
<br />
<pre><br />
<PictureStorageService<br />
name="PictureStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
format="jpeg|png"<br />
maxWidth="1024"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PictureStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>format</b> specifies the format of the stored picture. Values are "jpeg" and "png". The default is "jpeg".<br />
*<b>maxWidth</b> specifies the maximum width allowed for the stored picture. The default is 1024. Pictures wider than maxWidth are scaled down to masxWidth. Pictures smaller than maxWidth are stored at their native size.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name unless it is overridden by the filenameTag attribute.<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8064MIRC CTP2020-11-25T17:12:56Z<p>Johnperry: /* PictureStorageService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PictureStorageService=====<br />
The PictureStorageService stores images extracted from DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. The operation of this stage is similar to that of the DirectoryStorageService except that it only operates on DicomObjects and it stores only the extracted picture, with no accompanying information.<br />
<br />
<pre><br />
<PictureStorageService<br />
name="PictureStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
format="jpeg|png"<br />
maxWidth="1024"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PictureStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>format</b> specifies the format of the stored picture. Values are "jpeg" and "png". The default is "jpeg".<br />
*<b>maxWidth</b> specifies the maximum width allowed for the stored picture. The default is 1024. Pictures wider than maxWidth are scaled down to masxWidth. Pictures smaller than maxWidth are stored at their native size.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name unless it is overridden by the filenameTag attribute.<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8063MIRC CTP2020-11-25T17:08:57Z<p>Johnperry: /* DirectoryStorageService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PictureStorageService=====<br />
The PictureStorageService stores images extracted from DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. The operation of this stage is similar to that of the DirectoryStorageService<br />
<br />
<pre><br />
<PictureStorageService<br />
name="PictureStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
format="jpeg|png"<br />
maxWidth="1024"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PictureStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>format</b> specifies the format of the stored picture. Values are "jpeg" and "png". The default is "jpeg".<br />
*<b>maxWidth</b> specifies the maximum width allowed for the stored picture. The default is 1024. Pictures wider than maxWidth are scaled down to masxWidth. Pictures smaller than maxWidth are stored at their native size.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name unless it is overridden by the filenameTag attribute.<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_CTP_Launcher_Configuration_Editor&diff=8062The CTP Launcher Configuration Editor2020-09-17T15:36:36Z<p>Johnperry: </p>
<hr />
<div>This article describes how to use the CTP Launcher program to edit the configuration file. The intended audience for this article is system administrators.<br />
<br />
The Launcher program is the standard way to start and stop CTP when CTP is not running as a service. It displays a window containing a tabbed pane with these tabs:<br />
<br />
* General: Tables for setting important parameters, plus Start and Stop buttons and a button to launch a browser and access the CTP home page.<br />
* Version: A table displaying the key version information for CTP, its main libraries, plus Java and the ImageIO Tools.<br />
* System: A table displaying all the Java system properties.<br />
* Environment: A table displaying all the operating system environment variables.<br />
* Configuration: A GUI for editing the CTP configuration file.<br />
* Console: A live pane displaying the system and error output streams.<br />
* Log: A static pane displaying the CTP log file, with a button to refresh the display manually.<br />
<br />
This article describes the Configuration pane. After starting the Launcher program, click the Configuration tab. In the left pane, a tree displays the structure of the configuration file. Clicking on any node in the tree displays all the allowed attributes and child elements of the selected node, with text fields for changing the values. In the left pane, Pipeline stages and Plugins can be rearranged by dragging their icons and dropping them onto other nodes.<br />
<br />
[[Image:ConfigPane-form.PNG|thumb|right|400px|A node viewed as an editable form]]<br />
[[Image:ConfigPane-XML.PNG|thumb|right|400px|A node viewed as non-editable XML]]<br />
<br />
The window has a menu bar with the following menus and menu items:<br />
<br />
* File: <br />
** Save (CTRL-S): Makes a backup copy of the current <tt>config.xml</tt> file and then saves the edited configuration in the <tt>config.xml</tt> file. Backup files are located in the <b><tt>CTP</tt></b> directory. They have names with the form <b><tt>config[{n}].xml</tt></b>, where <b><tt>{n}</tt></b> is an integer. Higher integers are more recent. Before saving the edited configuration, the configuration is checked to see if it contains duplicate ports or duplicate root directories. Duplicate ports will abort the save function. Duplicate root directories generate a warning, allowing the user to decide whether to proceed or abort the save function.<br />
** Delete backups: Deletes all the old backups of the configuration (files with names in the form <b><tt>config[{n}].xml</tt></b>).<br />
* Edit: <br />
** Remove (CTRL-R): Removes the selected node (if removing the node is allowed). No Undo function is currently provided, and no "Are you sure?" confirmation is required, so be careful.<br />
* View:<br />
** Form (CTRL-F): Displays the selected node as an editable form in the right pane. When displaying a node as an editable form, only the attributes of the node are displayed; child elements must be individually selected to edit them. Note that if a node (for example the root node, <b><tt>Configuration</tt></b>) has no allowed attributes, the right pane is blank.<br />
** XML (CTRL-D): Displays the selected node as XML in the right pane. The XML is not editable. The editor knows the default values for all attributes and does not include attributes that have the default values. When displaying a node as XML, all the child nodes are also included.<br />
** Expand all (CTRL-E): Expands all tree nodes in the left pane.<br />
** Collapse all (CTRL-W): Collapses all tree nodes in the left pane.<br />
* Plugin: <br />
** One item for each Plugin known to the system. Selecting an item adds the corresponding Plugin to the configuration. If a Plugin node is selected, the new Plugin is added immediately after it. If no Plugin node is selected, the new Plugin is added just before the first Pipeline.<br />
* Pipeline:<br />
** New Pipeline (CTRL-N): Adds one empty Pipeline node to the end of the configuration.<br />
** One item for each standard pipeline known to the system. Selecting an item adds the entire pipeline to the end of the configuration.<br />
* ImportService:<br />
** One item for each ImportService known to the system. To insert an ImportService into the configuration, select either a Pipeline node or a Pipeline stage node. If a Pipeline node is selected, an ImportService is added to the end of the selected Pipeline. If a Pipeline stage is selected, an ImportService is added immediately after the selected stage.<br />
* Processor:<br />
** One item for each Processor known to the system. To insert a Processor into the configuration, select either a Pipeline node or a Pipeline stage node. If a Pipeline node is selected, a Processor is added to the end of the selected Pipeline. If a Pipeline stage is selected, a Processor is added immediately after the selected stage.<br />
* StorageService:<br />
** One item for each StorageService known to the system. To insert a StorageService into the configuration, select either a Pipeline node or a Pipeline stage node. If a Pipeline node is selected, a StorageService is added to the end of the selected Pipeline. If a Pipeline stage is selected, a StorageService is added immediately after the selected stage.<br />
* ExportService:<br />
** One item for each ExportService known to the system. To insert an ExportService into the configuration, select either a Pipeline node or a Pipeline stage node. If a Pipeline node is selected, an ExportService is added to the end of the selected Pipeline. If a Pipeline stage is selected, an ExportService is added immediately after the selected stage.<br />
* Children:<br />
** One item for each child element allowed to be added to the currently selected Pipeline stage. Child elements are only allowed in the Server element and in Pipeline stages.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_DicomAnonymizerTool&diff=8061The DicomAnonymizerTool2020-07-14T18:07:55Z<p>Johnperry: </p>
<hr />
<div>The DicomAnonymizerTool is a command-line program that processes a single file or a tree of directories using pipeline stages like those in CTP. It contains a DicomFilter, a DicomPixeAnonymizer, and a DicomAnonymizer. Each of the stages can be enabled, disabled, or configured through command-line parameters.<br />
<br />
The installer for the program can be obtained at http://mirc.rsna.org/download/DicomAnonymizerTool-installer.jar.<br />
<br />
To install the program, run the installer and select a directory. The installer will create a subdirectory called DicomAnonymizerTool in the selected directory and place all the necessary files in it.<br />
<br />
The program runs on Java 7 or better, including Java 9 and 10.<br />
<br />
To run the program, open a command window in the program's directory and run the program from the command line.<br />
<br />
If the program is run with no command-line parameters, it will list help information and information about the configuration of the platform on which it is running:<br />
<br />
<pre><br />
D:\JavaPrograms\DicomAnonymizerTool>java -jar DAT.jar<br />
Usage: java -jar DAT.jar {parameters}<br />
where:<br />
-in {input} specifies the file or directory to be anonymized<br />
If {input} is a directory, all files in it and its subdirectories are processed.<br />
-out {output} specifies the file or directory in which to store the anonymized file or files.<br />
If -out is missing and -in specifies a file, the anonymized file is named {input}-an.<br />
If -out is missing and -in specifies a directory, an output directory named {input}-an is created.<br />
If {output} is missing and -in specifies a file, the anonymized file overwrites {input}<br />
If {output} is present and -in specifies a file, the anonymized file is named {output}<br />
If {output} is present and -in specifies a directory, an output directory named {output} is created.<br />
-f {scriptfile} specifies the filter script.<br />
If -f is missing, all files are accepted.<br />
If {scriptfile} is missing, the default script is used.<br />
-da {scriptfile} specifies the anonymizer script.<br />
If -da is missing, element anonymization is not performed.<br />
If {scriptfile} is missing, the default script is used.<br />
-p{param} "{value}" specifies a value for the specified parameter.<br />
{value} must be encapsulated in quotes.<br />
-e{element} "{script}" specifies a script for the specified element.<br />
{element} may be specified as a DICOM keyword, e.g. -ePatientName.<br />
{element} may be specified as (group,element), e.g. -e(0010,0010).<br />
{element} may be specified as [group,element], e.g. -e[0010,0010].<br />
{element} may be specified as groupelement, e.g. -e00100010.<br />
{script} must be encapsulated in quotes.<br />
-lut {lookuptablefile} specifies the anonymizer lookup table properties file.<br />
If -lut is missing, the default lookup table is used.<br />
-dpa {pixelscriptfile} specifies the pixel anonymizer script file.<br />
If -dpa is missing, pixel anonymization is not performed.<br />
If {pixelscriptfile} is missing, the default pixel script is used.<br />
-dec specifies that the image is to be decompressed if the pixel anonymizer requires it.<br />
-rec specifies that the image is to be recompressed after pixel anonymization if it was decompressed.<br />
-test specifies that the pixel anonymizer is to blank regions in mid-gray.<br />
-check {frame} specifies that the anonymized image is to be tested to ensure that the images load.<br />
If -check is missing, no frame checking is done.<br />
If {frame} is missing, only the last frame is checked.<br />
If {frame} is specified as first, only the first frame is checked.<br />
If {frame} is specified as last, only the last frame is checked.<br />
If {frame} is specified as all, all frames are checked.<br />
-n {threads} specifies the number of parallel threads used for processing.<br />
-v specifies verbose output<br />
<br />
Configuration:<br />
os.name: Windows 10<br />
java.version: 10.0.1<br />
sun.arch.data.model: 64<br />
java.home: C:\Program Files\Java\jre-10.0.1<br />
clib: D:\JavaPrograms\DicomAnonymizerTool\clibwrapper_jiio-1.2-pre-dr-b04.jar<br />
jai: D:\JavaPrograms\DicomAnonymizerTool\jai_imageio-1.2-pre-dr-b04.jar<br />
jiio: null<br />
jiio sse2: null<br />
jiio util: null<br />
ImageIO Tools version: 1.2-pre-dr-b04<br />
<br />
This Java does not have the ImageIOTools native code extensions installed.<br />
<br />
Available codecs:<br />
R/W BMP<br />
R/W DICOM<br />
R/W GIF<br />
R/W JPEG<br />
R/W JPEG2000<br />
R/W JPG<br />
R/W PCX<br />
R/W PNG<br />
R/W PNM<br />
R/W RAW<br />
R RLE<br />
R/W TIFF<br />
R/W WBMP<br />
</pre><br />
<br />
All the default script files are contained in the same directory as the DAT.jar file. The defaults can be edited with any text editor, but changes will be overwritten during an upgrade. If specialized scripts are required, it is best to create new files for them and specify the script files in the appropriate program parameters.<br />
<br />
In special situations where one or more AnonymizerExtensions are required, a config.xml file must be put in the directory to specify the plugins. An example file might be:<br />
<br />
<pre><br />
<Configuration><br />
<Plugin<br />
baseDate="20000101"<br />
class="edu.emory.anonymizer.AnonymizerDateExtension"<br />
dateTableFile="D:/Data/Emory/testzip/testzip/TimeOfInjury.csv"<br />
id="ADEID"<br />
name="AnonymizerDateExtension"<br />
root="test/AnonymizerDateExtension"/><br />
</Configuration><br />
</pre><br />
<br />
When a config.xml file is found, it is loaded in the same way the CTP config.xml file is loaded, so there will be quite a bit of additional logging in the command window before file processing starts.<br />
<br />
IMPORTANT: For technical reasons, any AnonymizerExtension plugins must be contained in files with the names extensions1.jar, extensions2.jar, and/or extensions3.jar. No other extensions jars are loaded by the program. A single extensions jar file can contain many AnonymizerExtensions.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=Running_CTP_as_a_Windows_Service&diff=8060Running CTP as a Windows Service2019-11-30T15:54:49Z<p>Johnperry: /* Background */</p>
<hr />
<div>This article describes how to install CTP as a Windows service. It is intended for administrators who want CTP to start automatically when its host computer starts and shut down cleanly when its host computer shuts down. This is the most convenient way to run CTP on a Windows system for applications in which CTP acts a resource for a clinical trial or as a front-end to another system. <br />
<br />
==Background==<br />
The [http://mirc.rsna.org/download/CTP-installer.jar CTP installer] program is a self-extracting program that copies all the necessary files into a directory called <b><tt>CTP</tt></b> wherever the user requests it to be created. The installer creates a <b><tt>windows</tt></b> subdirectory containing these files:<br />
<br />
*<b>CTP.exe</b> - the service which is run by the Windows service manager. It starts and stops the CTP.jar program.<br />
*<b>CTPw.exe</b> - the service monitor which allows the administrator to adjust the parameters which determine how CTP.jar runs.<br />
*<b>install.bat</b> - the Windows batch job which installs the CTP.exe service and provides a default set of parameters.<br />
*<b>uninstall.bat</b> - the Windows batch job which uninstalls the CTP.exe service.<br />
<br />
==Installing the CTP Service==<br />
To install the service:<br />
<ol><br />
<li> Log into Windows in an account with administrator privileges<br />
<li> Launch a command window with administrator privileges<br />
:* Click <b>Start</b><br />
:* Type <b>cmd</b><br />
:* Type <b>Ctrl-Shift-Enter</b><br />
</ol><br />
<ol start="3"> <br />
<li> Navigate to the <b>CTP\windows</b> directory<br />
<li> Enter the command: <b><tt>install.bat</tt></b><br />
<li> Close the command window<br />
</ol><br />
<br />
==Uninstalling the CTP Service==<br />
To uninstall the service:<br />
<ol><br />
<li> Log into Windows in an account with administrator privileges<br />
<li> Launch a command window with administrator privileges<br />
:* Click <b>Start</b><br />
:* Type <b>cmd</b><br />
:* Type <b>Ctrl-Shift-Enter</b><br />
</ol><br />
<ol start="3"> <br />
<li>Navigate to the <b>CTP\windows</b> directory.<br />
<li> Enter the command: <b><tt>uninstall.bat</tt></b><br />
<li> Close the command window<br />
</ol><br />
==C Runtime Library==<br />
When CTP runs as a Windows service, it requires the Microsoft C Runtime Library to be present. This is a file called <b>msvcr71.dll</b>. If CTP fails to start and the CTP/logs directory doesn't indicate another problem, the simplest thing to do is place a <u>copy</u> of the file in the Java <b>jre\bin</b> directory. The file can usually be found in the <b>C:\Windows\System32</b> directory. Do <u>not</u> remove the file from where you found it.<br />
<br />
==Changing the Service Parameters with the CTP Service Monitor==<br />
The <b>CTPw.exe</b> program provides control over all the parameters that the service uses. To run the program, double-click the <b>CTPw.exe</b> file. If Windows displays the User Account Control challenge, click <b>Allow</b>. The program displays the CTP Properties dialog:<br />
[[Image:CTP-properties-1.JPG|center]]<br />
<br />
The properties dialog can be used to start or stop the service manually, but it is generally better to use the Windows service manager.<br />
<br />
===Changing the Startup Type===<br />
The CTP service is initially configured to require that the service be started manually. This can be changed to <b>Automatic</b> on the <b>General</b> tab if it is necessary that the service start automatically when the host computer starts.<br />
<br />
===Changing the Java Parameters===<br />
The CTP service is initially configured to allocate 128MB to the Java memory pool and to allow the memory pool to expand to 512MB if necessary as it runs. For most applications, this is sufficient. For systems that implement many pipelines handling large images or that employ pipeline stages that build large databases, it may be desirable to change these settings. To do so, click the <b>Java</b> tab to see this page:<br />
[[Image:CTP-properties-2.JPG|center]]<br />
<br />
===Changing Other Parameters===<br />
<br />
If you upgrade your Java and the <b>Use default</b> box is checked on the <b>Java</b> tab, the service will switch to the new Java the next time it starts. If you have multiple Java versions and you want to run a different one from the default, uncheck the box and specify the path to the desired <b><tt>jvm.dll</tt></b> file.<br />
<br />
Sophisticated administrators may consider changing the account under which the service runs. This can be done on the <b>Log On</b> tab.<br />
<br />
Do <u>not</u> change the Java Classpath parameter, even if you are a developer and you think you must. The Java Classpath parameter is only used to get CTP.jar running. After that, CTP overwrites the classpath with the jars it finds in the <b><tt>CTP/libraries</tt></b> directory. See [[Extending CTP]], and note especially [[Extending CTP#Building an Extension JAR | Building an Extension JAR]].<br />
<br />
==Technical Details==<br />
This section is included for the interested technophile. The information contained in this section is not required for installation or operation of the program. <br />
<br />
The <b>CTP.exe</b> program is the <b>Apache Commons Daemon</b> which is used to run Tomcat. It is used here with no modification except to change its name. The name defines the name by which the Windows service manager knows the service, and it cannot be changed without uninstalling the service and reinstalling it under a new name.<br />
<br />
The daemon calls a static start method in the main class of the Java program it runs. The daemon requires that the start method not return until the Java program ends. The daemon stops the Java program by calling a static stop method. The start and stop classes and methods are specified when the service is installed, and they are stored in the Windows registry. <br />
<br />
The <b><tt>install.bat</tt></b> file provides all the parameters required to run the service and launch CTP.jar. The CTP installer modifies a template <b><tt>install.bat</tt></b> file when it installs the file in the <b><tt>CTP\windows</tt></b> directory, replacing the <b><tt>${home}</tt></b> fields with the absolute path to the <b><tt>CTP</tt></b> directory. This is the template file:<br />
<br />
<pre><br />
CTP.exe ^<br />
//IS//CTP ^<br />
--Install="${home}"\windows\CTP.exe ^<br />
--Description="RSNA CTP Service" ^<br />
--Startup="auto" ^<br />
--Jvm=auto ^<br />
--StartMode=jvm ^<br />
--JvmMs=128 ^<br />
--JvmMx=512 ^<br />
--Classpath="libraries\CTP.jar" ^<br />
--StartPath="${home}" ^<br />
--StartClass=org.rsna.ctp.ClinicalTrialProcessor ^<br />
--StartMethod=startService ^<br />
--StartParams=start ^<br />
--StopMode=jvm ^<br />
--StopPath="${home}" ^<br />
--StopClass=org.rsna.ctp.ClinicalTrialProcessor ^<br />
--StopMethod=stopService ^<br />
--StopParams=stop ^<br />
--LogPath="${home}"\logs ^<br />
--StdOutput=auto ^<br />
--StdError=auto<br />
</pre><br />
The full set of parameters which the service supports is described on the [http://commons.apache.org/daemon/procrun.html Apache Commons] website.<br />
<br />
The <b><tt>uninstall.bat</tt></b> file is very simple:<br />
<pre><br />
CTP.exe //DS//CTP <br />
</pre><br />
<br />
The <b>CTPw.exe</b> program is the Apache service monitor which is part of the Commons Daemon project. It is used here with no modification except to change the name and to force it to run with elevated privileges, thus allowing it to be run with a simple double-click. The name of the program must correspond to the name of the service program. For example, CTPw.exe corresponds to CTP.exe, and tomcat6w.exe corresponds to tomcat6.exe.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools&diff=8059Java Advanced Imaging ImageIO Tools2019-10-31T11:57:12Z<p>Johnperry: /* Native Libraries */</p>
<hr />
<div>This article captures current information about the Java Advanced Imaging ImageIO Tools to document exactly what files are involved.<br />
<br />
The ImageIO Tools consist of two <b>jar</b> files plus one or more files which are in native code for the platform. The names in the tables below are the ones that appeared in versions 1.0 and 1.1. As the ImageIO Tools progress, the names of the files may accumulate release identification, as in <tt><b>jai_imageio-1.2-pre-dr-b04.jar</b></tt>.<br />
<br />
==JAR Files==<br />
<table border="1" style="padding:2px;"><br />
<tr><th>File name</th><th>Description</th><th>Typical Location</th></tr><br />
<tr><td style="padding:5px;">jai_imageio.jar</td><td style="padding:5px;">JAR file containing core JAI Image I/O class files</td><td style="padding:5px;"><b>jre/lib/ext</b></td></tr><br />
<tr><td style="padding:5px;">clibwrapper_jiio.jar</td><td style="padding:5px;">codecLib JNI interfaces</td><td style="padding:5px;"><b>jre/lib/ext</b></td></tr><br />
</table><br />
<br />
==Native Libraries==<br />
<table border="thin solid gray"><br />
<tr><th>File name</th><th>Description</th><th>Platform</th><th>Typical Location</th></tr><br />
<tr><td style="padding:5px;">libclib_jiio.so</td><td style="padding:5px;">mediaLib JNI shared libraries</td><td style="padding:5px;">Linux</td><td style="padding:5px;"><b>jre/i386 or jre/lib/amd64</b></td></tr><br />
<tr><td style="padding:5px;">clib_jiio.dll</td><td style="padding:5px;">codecLib JNI shared libraries</td><td style="padding:5px;">Windows</td><td style="padding:5px;"><b>jre/bin</b></td></tr><br />
<tr><td style="padding:5px;">clib_jiio_sse2.dll</td><td style="padding:5px;">mediaLib JNI DLL libraries</td><td style="padding:5px;">Windows</td><td style="padding:5px;"><b>jre/bin</b></td></tr><br />
<tr><td style="padding:5px;">clib_jiio_util.dll</td><td style="padding:5px;">Utilities</td><td style="padding:5px;">Windows</td><td style="padding:5px;"><b>jre/bin</b></td></tr><br />
</table><br />
<br />
==Installation Files==<br />
The Oracle site no longer provides links to the ImageIO Tools version 1.1 or later. The files necessary to install the tools on several platforms have been put on the RSNA MIRC site.<br />
<br />
===Windows===<br />
The Windows installer for the ImageIO Tools is available at: [http://mirc.rsna.org/ImageIO/jai_imageio-1_1-lib-windows-i586-jre.exe jai_imageio-1_1-lib-windows-i586-jre.exe]<br />
<br />
A zip file containing the files (not required if using the installer) is available at: [http://mirc.rsna.org/ImageIO/win-i686.zip http://mirc.rsna.org/ImageIO/win-i686.zip]<br />
<br />
===Linux===<br />
A zip file for installing the ImageIO Tools on an i686 platform is available at: [http://mirc.rsna.org/ImageIO/linux-i686.zip http://mirc.rsna.org/ImageIO/linux-i686.zip]<br />
<br />
A zip file for installing the ImageIO Tools on an x86_64 platform is available at: [http://mirc.rsna.org/ImageIO/linux-x86_64.zip http://mirc.rsna.org/ImageIO/linux-x86_64.zip]<br />
<br />
===Solaris===<br />
A zip file for installing the ImageIO Tools on an i686 platform is available at: [http://mirc.rsna.org/ImageIO/solaris-i686.zip http://mirc.rsna.org/ImageIO/solaris-i686.zip]<br />
<br />
A zip file for installing the ImageIO Tools on a SPARC platform is available at: [http://mirc.rsna.org/ImageIO/solaris-sparc.zip http://mirc.rsna.org/ImageIO/solaris-sparc.zip]<br />
<br />
A zip file for installing the ImageIO Tools on a SPARC v9 platform is available at: [http://mirc.rsna.org/ImageIO/solaris-sparcv9.zip http://mirc.rsna.org/ImageIO/solaris-sparcv9.zip]<br />
<br />
A zip file for installing the ImageIO Tools on an x86_64 platform is available at: [http://mirc.rsna.org/ImageIO/solaris-x86_64.zip http://mirc.rsna.org/ImageIO/solaris-x86_64.zip]<br />
<br />
===Macintosh===<br />
A zip file containing the two jar files is available at [http://mirc.rsna.org/ImageIO/ImageIOJars.zip http://mirc.rsna.org/ImageIO/ImageIOJars.zip].<br />
<br />
No native libraries are available for the Macintosh. Place the two jar files into:<br />
<br />
:<b><tt>/Library/Java/JavaVirtualMachines/jdk.../lib/ext</tt></b>.<br />
<br />
==Notes==<br />
#The <b>jar</b> files are required.<br />
#The dll/so files are optional.<br />
#The dll/so files provide acceleration for certain image types.<br />
#The dll/so files may also provide support for additional image types.<br />
#You can force the ImageIO Tools not to use the native libraries by starting a program with this switch:<br />
::<b>-Dcom.sun.media.imageio.disableCodecLib=true</b><br />
<br />
Much more information is available at http://download.java.net/media/jai-imageio/builds/release/1.1/INSTALL-jai_imageio.html, although this information seems to be out of date.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=DicomEditor&diff=8058DicomEditor2019-10-02T14:18:38Z<p>Johnperry: </p>
<hr />
<div>DicomEditor is a utility program for viewing, editing, and de-identifying DICOM images. It is written in Java and requires Java 1.5 and the [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools JAI ImageIO Tools] to be on the target computer. Its intended use is as a test program for MIRC development, but it can be used generally to modify DICOM images. <br />
<br />
==Installation==<br />
The installer for DicomEditor is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane in the left pane of the MIRC home page to obtain a list of all the available software. <br />
<br />
To use the program, download the installer and run it. It will create a folder called <b>DicomEditor</b> and put the required files inside it. To launch the program, double-click the <b>DicomEditor.jar</b> file. You can create a shortcut to that file and put it anyplace convenient.<br />
<br />
==The Directory Tab==<br />
The <b>Directory</b> tab displays a split pane with a <b>Director</b> pane on the left and a <b>Results</b> pane on the right. The <b>Directory</b> pane is used to navigate to a file or a folder of interest. The pull-down menu in the header of the left pane lets you choose the root (drive) file system. The button in the footer bar lets you specify the extensions to accept. <br />
<br />
Once a file or folder is selected in the left pane, clicking the <b>Anonymize</b> button in the footer bar of the right pane starts the de-identification process. The progress is shown in the <b>Results</b> pane. <br />
* If an individual file is selected in the <b>Directory</b> pane, that is the only file that is processed. <br />
* If a folder is selected and the <b>Include subdirectories</b> checkbox in the footer bar is not checked, then all the files in the folder are processed. <br />
* If a folder is selected and the checkbox is also checked, then the program processes the files in the folder and all its subfolders, walking the directory tree below the selected folder. Only files matching the specified extensions are processed. <br />
* If the <b>Change names of anonymized files</b> box is checked in the footer of the <b>Results</b> pane, the anonymized files are created with names ending in <b>-no-phi</b>. If the box is not checked, the files are overwritten with the processed results. When processing with the box checked, the anonymizer will not anonymize any file whose name ends in <b>-no-phi</b>.<br />
* If the <b>Use SOPIUID for name</b> box is checked in the footer of the <b>Results</b> pane, the anonymized files are created using their SOP Instance UIDs for the file names. This check box takes priority over the <b>Change names of anonymized files</b> box. If the file's name is already its SOP Instance UID, it is overwritten by the processed file.<br />
<br />
Certain other processing functions are provided in addition to anonymization:<br />
* <b>Fix DICOM</b> verifies the VR values of all the elements in the file, changing any VRs which do not match the DICOM Data Dictionary. <br />
* <b>Clear Preamble</b> overwrites the preambles of Part 10 files with all zeroes.<br />
* If the <b>Alt</b> key is held down while clicking the <b>Clear Preamble</b> button, the preambles and <b>DICM</b> identifiers are removed from any files that do not contain a file metainfo group (group 2).<br />
<br />
During processing, if the <b>Force IVR-LE Syntax</b> box is checked, the processed files are written with the Implicit Value Representation Little Endian transfer syntax.<br />
<br />
==The DICOM Viewer Tab==<br />
The <b>DICOM Viewer</b> tab displays a DICOM image along with its metadata. Certain elements in the metadata (most of the ones that are textual) are editable. <br />
<br />
To open a DICOM file, click the <b>Open</b> button and use the file chooser to navigate to the desired file. To close the currently open image, click the <b>Close</b> button. <br />
<br />
To edit an element, click its <b>(group,element)</b> designation. A dialog box will appear allowing you to change the value of the element. <br />
<br />
If you have made one or more changes to an image, the <b>Save</b> and <b>Save All</b> buttons will be enabled. <b>Save</b> only saves the changes made to the current image. <b>Save All</b> applies the changes to all the images with the same <b>StudyInstanceUID</b> in the current directory. <br />
<br />
An element name displayed in red is one that is referenced by a script that could cause the anonymizer to call its <b>quarantine</b> function and leave the image untouched. If you anonymize an image and the <b>Results</b> pane shows that the anonymizer called the quarantine function, look at the values in the red elements and see if there is something wrong. <br />
<br />
To save a JPEG version of the currently displayed image, click the <b>Save As JPEG</b> button. A dialog box will appear allowing you to specify the maximum width of the saved image. The actual width of the saved image will be the minimum of the width of the DICOM image and the maximum width you specify. The height will be scaled to maintain the aspect ratio.<br />
<br />
==The DICOM Anonymizer Tab==<br />
DicomEditor uses the MIRC anonymizer to process files. The processing for each individual DICOM element can be specified in the <b>DICOM Anonymizer</b> tab. For a description of the script language, see [[The MIRC DICOM Anonymizer]].<br />
<br />
==The Help Tab==<br />
The Help tab contains a list of all the script functions as a quick reference. <br />
If you find any problems with the program, please post them on the RSNA Forum Site in the MIRC Forum's User Comments thread.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=DicomEditor&diff=8057DicomEditor2019-10-02T14:18:10Z<p>Johnperry: </p>
<hr />
<div>DicomEditor is a utility program for viewing, editing, and de-identifying DICOM images. It is written in Java and requires Java 1.5 and the [[http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools JAI ImageIO Tools]] to be on the target computer. Its intended use is as a test program for MIRC development, but it can be used generally to modify DICOM images. <br />
<br />
==Installation==<br />
The installer for DicomEditor is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane in the left pane of the MIRC home page to obtain a list of all the available software. <br />
<br />
To use the program, download the installer and run it. It will create a folder called <b>DicomEditor</b> and put the required files inside it. To launch the program, double-click the <b>DicomEditor.jar</b> file. You can create a shortcut to that file and put it anyplace convenient.<br />
<br />
==The Directory Tab==<br />
The <b>Directory</b> tab displays a split pane with a <b>Director</b> pane on the left and a <b>Results</b> pane on the right. The <b>Directory</b> pane is used to navigate to a file or a folder of interest. The pull-down menu in the header of the left pane lets you choose the root (drive) file system. The button in the footer bar lets you specify the extensions to accept. <br />
<br />
Once a file or folder is selected in the left pane, clicking the <b>Anonymize</b> button in the footer bar of the right pane starts the de-identification process. The progress is shown in the <b>Results</b> pane. <br />
* If an individual file is selected in the <b>Directory</b> pane, that is the only file that is processed. <br />
* If a folder is selected and the <b>Include subdirectories</b> checkbox in the footer bar is not checked, then all the files in the folder are processed. <br />
* If a folder is selected and the checkbox is also checked, then the program processes the files in the folder and all its subfolders, walking the directory tree below the selected folder. Only files matching the specified extensions are processed. <br />
* If the <b>Change names of anonymized files</b> box is checked in the footer of the <b>Results</b> pane, the anonymized files are created with names ending in <b>-no-phi</b>. If the box is not checked, the files are overwritten with the processed results. When processing with the box checked, the anonymizer will not anonymize any file whose name ends in <b>-no-phi</b>.<br />
* If the <b>Use SOPIUID for name</b> box is checked in the footer of the <b>Results</b> pane, the anonymized files are created using their SOP Instance UIDs for the file names. This check box takes priority over the <b>Change names of anonymized files</b> box. If the file's name is already its SOP Instance UID, it is overwritten by the processed file.<br />
<br />
Certain other processing functions are provided in addition to anonymization:<br />
* <b>Fix DICOM</b> verifies the VR values of all the elements in the file, changing any VRs which do not match the DICOM Data Dictionary. <br />
* <b>Clear Preamble</b> overwrites the preambles of Part 10 files with all zeroes.<br />
* If the <b>Alt</b> key is held down while clicking the <b>Clear Preamble</b> button, the preambles and <b>DICM</b> identifiers are removed from any files that do not contain a file metainfo group (group 2).<br />
<br />
During processing, if the <b>Force IVR-LE Syntax</b> box is checked, the processed files are written with the Implicit Value Representation Little Endian transfer syntax.<br />
<br />
==The DICOM Viewer Tab==<br />
The <b>DICOM Viewer</b> tab displays a DICOM image along with its metadata. Certain elements in the metadata (most of the ones that are textual) are editable. <br />
<br />
To open a DICOM file, click the <b>Open</b> button and use the file chooser to navigate to the desired file. To close the currently open image, click the <b>Close</b> button. <br />
<br />
To edit an element, click its <b>(group,element)</b> designation. A dialog box will appear allowing you to change the value of the element. <br />
<br />
If you have made one or more changes to an image, the <b>Save</b> and <b>Save All</b> buttons will be enabled. <b>Save</b> only saves the changes made to the current image. <b>Save All</b> applies the changes to all the images with the same <b>StudyInstanceUID</b> in the current directory. <br />
<br />
An element name displayed in red is one that is referenced by a script that could cause the anonymizer to call its <b>quarantine</b> function and leave the image untouched. If you anonymize an image and the <b>Results</b> pane shows that the anonymizer called the quarantine function, look at the values in the red elements and see if there is something wrong. <br />
<br />
To save a JPEG version of the currently displayed image, click the <b>Save As JPEG</b> button. A dialog box will appear allowing you to specify the maximum width of the saved image. The actual width of the saved image will be the minimum of the width of the DICOM image and the maximum width you specify. The height will be scaled to maintain the aspect ratio.<br />
<br />
==The DICOM Anonymizer Tab==<br />
DicomEditor uses the MIRC anonymizer to process files. The processing for each individual DICOM element can be specified in the <b>DICOM Anonymizer</b> tab. For a description of the script language, see [[The MIRC DICOM Anonymizer]].<br />
<br />
==The Help Tab==<br />
The Help tab contains a list of all the script functions as a quick reference. <br />
If you find any problems with the program, please post them on the RSNA Forum Site in the MIRC Forum's User Comments thread.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_TFS&diff=8056MIRC TFS2019-10-02T14:16:17Z<p>Johnperry: /* JAI ImageIO Tools */</p>
<hr />
<div>This article describes the new version of the MIRC teaching file system (TFS) running as a plug-in on CTP. This article is intended for people interested in installing MIRC.<br />
<br />
===Background===<br />
MIRC - Medical Imaging Resource Center - is an RSNA project to provide tools for radiological teaching files and clinical trials. Beginning in 2000, the project has produced many software releases.<br />
<br />
The earliest versions of MIRC were restricted to Microsoft platforms, using IIS as the server (versions 1-9). Starting with version 10, MIRC was rewritten in Java to run on Tomcat. Those versions were denoted with the prefix <b>T</b> (T10-T36). <br />
<br />
The Tomcat-based versions supported both teaching files and clinical trials. In the clinical trials application, however, the extra complexity of the Tomcat installation was an impediment, so a special clinical trials application was developed called <b>CTP</b>. CTP contains its own embedded servlet container, providing the necessary capabilities from Tomcat without the need for a separate installation step. It also contains a more capable processing facility and anonymizers that implement the DICOM Supplement 142 de-identification profiles. For more information on CTP, see [[CTP-The RSNA Clinical Trial Processor]].<br />
<br />
As experience was gained with CTP, it became clear that it could serve as the servlet container for MIRC, providing both new features and simplified installation. To support MIRC, numerous extensions to CTP were implemented, the most important of which was the development of plug-ins, which provide processing capabilities outside the normal CTP pipelines. MIRC TFS is implemented as a single plug-in in this framework.<br />
<br />
In early 2012, the MIRC Committee changed the name of the teaching files application from MIRC to TFS. In the context of this article, MIRC and TFS are used as synonyms.<br />
<br />
The new MIRC TFS implementation is denoted with the <b>Z</b> prefix. The starting release identifier has been reset to <b>1</b>, so the first release is designated <b>Z1</b>.<br />
<br />
The CTP/MIRC TFS implementation is recommended for all new MIRC TFS installations.<br />
<br />
===Installation===<br />
<br />
Three components are required for running a MIRC TFS site under CTP:<br />
* Java<br />
* JAI ImageIO Tools<br />
* CTP and the MIRC TFS plug-in<br />
<br />
====Java====<br />
The Java 1.7 (or better) JRE must be present on the system. Java 1.8 is strongly recommended. Java is available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. <br />
<br />
:<em>When installing Java, make sure to obtain the 32-bit version, even if you are running on a 64-bit platform. Sophisticated users may be able to run the 64-bit versions on some platforms, but the gains would be minimal and the likelihood of encountering problems would be large.</em><br />
<br />
====JAI ImageIO Tools====<br />
MIRC requires that the [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools Java Advanced Imaging ImageIO Tools] be present on the system. It is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. You must get the jre version (for Windows, it has a name like jai_imageio-1_1-lib-windows-i586-jre.exe), not the one for the CLASSPATH, which does not include <b>-jre</b> in the name. <br />
<br />
:<em>Note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required.</em><br />
<br />
====CTP/TFS====<br />
[[Image:MIRC-installer.jpg|thumb|right|400px]] The installer for MIRC TFS is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane to obtain a list of all the available software. The <b>TFS-installer</b> available on the site includes CTP and all the libraries required to run the teaching files application.<br />
<br />
Once Java and the ImageIO Tools are installed, download the installer and place it on the disk on which you intend to install or upgrade the CTP program. Do <b>not</b> run it without downloading it and storing it locally.<br />
<br />
:<em>For convenience, it is recommended (but not required) that a folder called </em><b><tt>JavaPrograms</tt></b><em> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP there. This is especially helpful during future upgrades.</em><br />
<br />
To run the TFS installer, double-click the <tt><b>TFS-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar TFS-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b><tt>CTP</tt></b> in the selected location and places several files and directories in it. <br />
<br />
When the installer runs, it checks several parameters of the system and highlights in red any components that are not correct for the running of CTP.<br />
<br clear="right"/><br />
<br />
===Running CTP with the MIRC TFS Plug-in===<br />
Note that TFS is not a stand-alone program; it is a plug-in to CTP in the same way that previous versions of MIRC were webapps that ran under Tomcat. Therefore, it is most correct to speak of running <b>CTP</b> rather than <b>TFS</b> or <b>MIRC</b>, so that terminology is used here.<br />
<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows or Linux service. See [[Running CTP as a Windows Service]] or [[Running CTP as a Linux Service]] for instructions. <br />
<br />
[[Image:CTP-launcher.jpg|thumb|right|400px]] The <b><tt>Launcher.jar</tt></b> program can be started by double-clicking the file or by launching a command window and entering the command:<br />
:<tt><b>java -jar Launcher.jar</b></tt><br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>TFS Home Page</b> button launches the user's browser and goes directly to the main TFS page.<br />
<br />
To stop the program, either click the <b><tt>Stop</tt></b> button on the dialog or log in as a user with the <tt>shutdown</tt> privilege and click the <b>Shutdown</b> item in the <b>Admin > CTP</b> menu on the main query page. As a convenience, a user with the <tt>admin</tt> privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br clear="right"/><br />
<br />
==Accessing TFS from the Network==<br />
When CTP starts, it loads the MIRC plug-in. The MIRC plug-in installs several servlets to provide access to the system. The query page serves as the portal into all the TFS features. Its URL is:<br />
:<b><tt>/query</tt></b><br />
<br />
Several other URLs also end up at the query page, but they do so by redirecting the browser, so it is most efficient to use the actual query page URL. Other URLs that go to the query page are:<br />
:<b><tt>/</tt></b><br />
:<b><tt>/mirc</tt></b><br />
<br />
==Server Configuration==<br />
[[Image:UserManager.jpg|thumb|right|400px]] When the program is first installed, two users are provided. One user, with the name <b><tt>admin</tt></b> and password <b><tt>password</tt></b>, is intended for general system administration. The other user, with the name <b><tt>king</tt></b> and password <b><tt>password</tt></b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user. Most MIRC administrators log in as the <b><tt>admin</tt></b> user.<br />
<br />
After installing and starting CTP and MIRC TFS, access the query page, click the <b>Login</b> button to log in as the <b><tt>admin</tt></b> user, and then go to the <b>Admin > User Manager</b> menu item. This will display a page allowing you to add and modify users. To start, check all the boxes in the <b>admin</b> user except <b>shutdown</b> and then click the save icon in the upper right corner of the page. The page will re-display, showing that the changes have been made. You should change the passwords of these accounts at this time as well, using the unlabelled column at the right side of the table. If you need to create accounts for other users, use the blank line at the bottom of the table. Each time the save icon is clicked, a new blank line will appear. When all the changes have been made, click the home icon in the upper right corner of the page to go back to the query page.<br />
<br clear="right"/><br />
<br />
TFS has two user interfaces, the <b>Classic UI</b> and the <b>Integrated UI</b>. These present almost the same functionality in two different ways. Each only shows the user those functions that the user's privileges allow him to access.<br />
<br />
::[[Image:ClassicUI.jpg|400px|Classic UI]] [[Image:IntegratedUI.jpg|400px|Integrated UI]]<br />
<br />
Individual users can choose their preferred UI and switch between them easily. As the administrator, you can choose the default UI to be presented to an unauthenticated user. To do so, go to the <b>Admin > Query Service Admin</b> menu item. On that page, select the desired radio button in the <b>Default query page user interface</b> field and then click the save button:<br />
<br />
[[Image:QSAdmin.jpg|center|500px]] <br />
<br />
On the Query Service Admin page, you can also control which other TFS sites are available to be queried. After making any changes, click the save icon and then click the home icon to return to the main query page.<br />
<br />
At this point, the site is ready for operation.<br />
<br />
==Client Configuration for Document Authoring==<br />
TFS provides authoring tools to create MIRCdocuments that are accessed through the user's browser. <br />
<br />
When authoring a MIRCdocument, a special SVG viewer must be installed on the author's computer to allow images to be annotated. The free Adobe SVG viewer can be obtained from [http://www.adobe.com/svg/viewer/install/main.html the Adobe SVG Site]. Adobe no longer supports the SVG viewer, but it works just fine. At the bottom of the Adobe page, there is a table of versions for different operating systems. Adobe hasn’t updated the page since the late Pleistocene, and the last Windows version listed is XP, but it has been tested successfully on Vista and Windows 7 using IE7, 8, and 9, as well as the latest Firefox and Chrome.<br />
<br />
The SVG viewer is not required for displaying annotated images, only for creating the annotations themselves, so the viewer need only be installed on computers used by authors who wish to create annotations.<br />
<br />
==Advanced Configuration==<br />
In addition to plugins like the one that implements MIRC TFS, CTP supports sequences of processing steps called pipelines. Pipelines are described in [[CTP-The RSNA Clinical Trial Processor]]. MIRC employs pipelines to support the reception of DICOM images for the File Service, the DICOM Service, and the TCE Service. The MIRC pipelines are described in [[MIRC Pipelines]]. <br />
Each service pipeline has its own DICOM Storage SCP. The default ports for these SCPs are:<br />
* File Service: port 1081<br />
* DICOM Service: port 1082<br />
* TCE Service: port 1083.<br />
These ports can be changed to any unused ports on the system. After starting CTP/MIRC for the first time, click the <b>Log</b> button on the <b><tt>CTP-launcher</tt></b> dialog and see if there are any log entries indicating that an address was already in use. If so, see the [[MIRC Pipelines]] article and move the offending service to another port.<br />
<br />
==Using LDAP for Authentication==<br />
CTP can be configured to support LDAP for user authentication. See [[CTP Authentication Using LDAP]] for details.<br />
<br />
==Using OpenAM for Authentication==<br />
CTP can be configured to support OpenAM for user authentication. See [[CTP Authentication Using OpenAM]] for details.<br />
<br />
==Upgrading a Tomcat MIRC Site==<br />
To upgrade from the Tomcat MIRC implementation to the CTP MIRC implementation, there are two steps:<br />
* create a fresh installation of CTP MIRC<br />
* copy the existing Tomcat MIRC site to the CTP MIRC site.<br />
<br />
To assist in copying the old site to the new one, the CTP MIRC installation includes a program called <b><tt>Copier.jar</tt></b> in the <b><tt>CTP</tt></b> directory. To run the program, double-click the file or start it with the command:<br />
:<b><tt>java -jar Copier.jar</tt></b><br />
<br />
The <b><tt>Copier</tt></b> program can be run while the Tomcat MIRC site is running. The Tomcat MIRC site is not modified in any way.<br />
<br />
If the <b><tt>Copier</tt></b> program is run while the CTP MIRC site is running, it automatically stops the site.<br />
<br />
The <b><tt>Copier</tt></b> program copies:<br />
* the users' accounts<br />
* the users' names, affiliations, and contact information<br />
* the storage services:<br />
** all the MIRCdocuments<br />
** the settings:<br />
*** Storage Service tagline<br />
*** Author Service enable<br />
*** Submit Service enable<br />
*** Zip Service enable<br />
*** DICOM Service enable<br />
*** TCE Service enable<br />
*** autoindex enable<br />
*** maximum upload size<br />
*** JPEG quality parameter<br />
*** deleted documents timeout<br />
<br />
The following information is <u>not</u> copied:<br />
* the users' file cabinets<br />
* the shared file cabinet<br />
* the users' conferences<br />
* the shared conferences<br />
<br />
Notes: <br />
* If a user already exists in the CTP site, that user is not modified.<br />
* When copying a storage service, the program tries to find an existing storage service with the same name. If it finds one, it adds the documents to the existing storage service. If it does not find one, it creates a new storage service.<br />
* The program can be run multiple times without creating duplicate user accounts, storage services, or MIRCdocuments.<br />
* When the CTP MIRC site is first installed, one empty storage service is automatically provided. After copying from the Tomcat site to the CTP site, this storage service may still be empty. If you want to remove it, go to the Storage Service admin page and click the <b>Remove this Storage Service</b> button.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_TFS&diff=8055MIRC TFS2019-10-02T14:15:56Z<p>Johnperry: /* Background */</p>
<hr />
<div>This article describes the new version of the MIRC teaching file system (TFS) running as a plug-in on CTP. This article is intended for people interested in installing MIRC.<br />
<br />
===Background===<br />
MIRC - Medical Imaging Resource Center - is an RSNA project to provide tools for radiological teaching files and clinical trials. Beginning in 2000, the project has produced many software releases.<br />
<br />
The earliest versions of MIRC were restricted to Microsoft platforms, using IIS as the server (versions 1-9). Starting with version 10, MIRC was rewritten in Java to run on Tomcat. Those versions were denoted with the prefix <b>T</b> (T10-T36). <br />
<br />
The Tomcat-based versions supported both teaching files and clinical trials. In the clinical trials application, however, the extra complexity of the Tomcat installation was an impediment, so a special clinical trials application was developed called <b>CTP</b>. CTP contains its own embedded servlet container, providing the necessary capabilities from Tomcat without the need for a separate installation step. It also contains a more capable processing facility and anonymizers that implement the DICOM Supplement 142 de-identification profiles. For more information on CTP, see [[CTP-The RSNA Clinical Trial Processor]].<br />
<br />
As experience was gained with CTP, it became clear that it could serve as the servlet container for MIRC, providing both new features and simplified installation. To support MIRC, numerous extensions to CTP were implemented, the most important of which was the development of plug-ins, which provide processing capabilities outside the normal CTP pipelines. MIRC TFS is implemented as a single plug-in in this framework.<br />
<br />
In early 2012, the MIRC Committee changed the name of the teaching files application from MIRC to TFS. In the context of this article, MIRC and TFS are used as synonyms.<br />
<br />
The new MIRC TFS implementation is denoted with the <b>Z</b> prefix. The starting release identifier has been reset to <b>1</b>, so the first release is designated <b>Z1</b>.<br />
<br />
The CTP/MIRC TFS implementation is recommended for all new MIRC TFS installations.<br />
<br />
===Installation===<br />
<br />
Three components are required for running a MIRC TFS site under CTP:<br />
* Java<br />
* JAI ImageIO Tools<br />
* CTP and the MIRC TFS plug-in<br />
<br />
====Java====<br />
The Java 1.7 (or better) JRE must be present on the system. Java 1.8 is strongly recommended. Java is available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. <br />
<br />
:<em>When installing Java, make sure to obtain the 32-bit version, even if you are running on a 64-bit platform. Sophisticated users may be able to run the 64-bit versions on some platforms, but the gains would be minimal and the likelihood of encountering problems would be large.</em><br />
<br />
====JAI ImageIO Tools====<br />
MIRC requires that the [http://download.java.net/media/jai-imageio/builds/release/1.1/ Java Advanced Imaging ImageIO Tools] be present on the system. It is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. You must get the jre version (for Windows, it has a name like jai_imageio-1_1-lib-windows-i586-jre.exe), not the one for the CLASSPATH, which does not include <b>-jre</b> in the name. <br />
<br />
:<em>Note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required.</em><br />
<br />
====CTP/TFS====<br />
[[Image:MIRC-installer.jpg|thumb|right|400px]] The installer for MIRC TFS is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane to obtain a list of all the available software. The <b>TFS-installer</b> available on the site includes CTP and all the libraries required to run the teaching files application.<br />
<br />
Once Java and the ImageIO Tools are installed, download the installer and place it on the disk on which you intend to install or upgrade the CTP program. Do <b>not</b> run it without downloading it and storing it locally.<br />
<br />
:<em>For convenience, it is recommended (but not required) that a folder called </em><b><tt>JavaPrograms</tt></b><em> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP there. This is especially helpful during future upgrades.</em><br />
<br />
To run the TFS installer, double-click the <tt><b>TFS-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar TFS-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b><tt>CTP</tt></b> in the selected location and places several files and directories in it. <br />
<br />
When the installer runs, it checks several parameters of the system and highlights in red any components that are not correct for the running of CTP.<br />
<br clear="right"/><br />
<br />
===Running CTP with the MIRC TFS Plug-in===<br />
Note that TFS is not a stand-alone program; it is a plug-in to CTP in the same way that previous versions of MIRC were webapps that ran under Tomcat. Therefore, it is most correct to speak of running <b>CTP</b> rather than <b>TFS</b> or <b>MIRC</b>, so that terminology is used here.<br />
<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows or Linux service. See [[Running CTP as a Windows Service]] or [[Running CTP as a Linux Service]] for instructions. <br />
<br />
[[Image:CTP-launcher.jpg|thumb|right|400px]] The <b><tt>Launcher.jar</tt></b> program can be started by double-clicking the file or by launching a command window and entering the command:<br />
:<tt><b>java -jar Launcher.jar</b></tt><br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>TFS Home Page</b> button launches the user's browser and goes directly to the main TFS page.<br />
<br />
To stop the program, either click the <b><tt>Stop</tt></b> button on the dialog or log in as a user with the <tt>shutdown</tt> privilege and click the <b>Shutdown</b> item in the <b>Admin > CTP</b> menu on the main query page. As a convenience, a user with the <tt>admin</tt> privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br clear="right"/><br />
<br />
==Accessing TFS from the Network==<br />
When CTP starts, it loads the MIRC plug-in. The MIRC plug-in installs several servlets to provide access to the system. The query page serves as the portal into all the TFS features. Its URL is:<br />
:<b><tt>/query</tt></b><br />
<br />
Several other URLs also end up at the query page, but they do so by redirecting the browser, so it is most efficient to use the actual query page URL. Other URLs that go to the query page are:<br />
:<b><tt>/</tt></b><br />
:<b><tt>/mirc</tt></b><br />
<br />
==Server Configuration==<br />
[[Image:UserManager.jpg|thumb|right|400px]] When the program is first installed, two users are provided. One user, with the name <b><tt>admin</tt></b> and password <b><tt>password</tt></b>, is intended for general system administration. The other user, with the name <b><tt>king</tt></b> and password <b><tt>password</tt></b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user. Most MIRC administrators log in as the <b><tt>admin</tt></b> user.<br />
<br />
After installing and starting CTP and MIRC TFS, access the query page, click the <b>Login</b> button to log in as the <b><tt>admin</tt></b> user, and then go to the <b>Admin > User Manager</b> menu item. This will display a page allowing you to add and modify users. To start, check all the boxes in the <b>admin</b> user except <b>shutdown</b> and then click the save icon in the upper right corner of the page. The page will re-display, showing that the changes have been made. You should change the passwords of these accounts at this time as well, using the unlabelled column at the right side of the table. If you need to create accounts for other users, use the blank line at the bottom of the table. Each time the save icon is clicked, a new blank line will appear. When all the changes have been made, click the home icon in the upper right corner of the page to go back to the query page.<br />
<br clear="right"/><br />
<br />
TFS has two user interfaces, the <b>Classic UI</b> and the <b>Integrated UI</b>. These present almost the same functionality in two different ways. Each only shows the user those functions that the user's privileges allow him to access.<br />
<br />
::[[Image:ClassicUI.jpg|400px|Classic UI]] [[Image:IntegratedUI.jpg|400px|Integrated UI]]<br />
<br />
Individual users can choose their preferred UI and switch between them easily. As the administrator, you can choose the default UI to be presented to an unauthenticated user. To do so, go to the <b>Admin > Query Service Admin</b> menu item. On that page, select the desired radio button in the <b>Default query page user interface</b> field and then click the save button:<br />
<br />
[[Image:QSAdmin.jpg|center|500px]] <br />
<br />
On the Query Service Admin page, you can also control which other TFS sites are available to be queried. After making any changes, click the save icon and then click the home icon to return to the main query page.<br />
<br />
At this point, the site is ready for operation.<br />
<br />
==Client Configuration for Document Authoring==<br />
TFS provides authoring tools to create MIRCdocuments that are accessed through the user's browser. <br />
<br />
When authoring a MIRCdocument, a special SVG viewer must be installed on the author's computer to allow images to be annotated. The free Adobe SVG viewer can be obtained from [http://www.adobe.com/svg/viewer/install/main.html the Adobe SVG Site]. Adobe no longer supports the SVG viewer, but it works just fine. At the bottom of the Adobe page, there is a table of versions for different operating systems. Adobe hasn’t updated the page since the late Pleistocene, and the last Windows version listed is XP, but it has been tested successfully on Vista and Windows 7 using IE7, 8, and 9, as well as the latest Firefox and Chrome.<br />
<br />
The SVG viewer is not required for displaying annotated images, only for creating the annotations themselves, so the viewer need only be installed on computers used by authors who wish to create annotations.<br />
<br />
==Advanced Configuration==<br />
In addition to plugins like the one that implements MIRC TFS, CTP supports sequences of processing steps called pipelines. Pipelines are described in [[CTP-The RSNA Clinical Trial Processor]]. MIRC employs pipelines to support the reception of DICOM images for the File Service, the DICOM Service, and the TCE Service. The MIRC pipelines are described in [[MIRC Pipelines]]. <br />
Each service pipeline has its own DICOM Storage SCP. The default ports for these SCPs are:<br />
* File Service: port 1081<br />
* DICOM Service: port 1082<br />
* TCE Service: port 1083.<br />
These ports can be changed to any unused ports on the system. After starting CTP/MIRC for the first time, click the <b>Log</b> button on the <b><tt>CTP-launcher</tt></b> dialog and see if there are any log entries indicating that an address was already in use. If so, see the [[MIRC Pipelines]] article and move the offending service to another port.<br />
<br />
==Using LDAP for Authentication==<br />
CTP can be configured to support LDAP for user authentication. See [[CTP Authentication Using LDAP]] for details.<br />
<br />
==Using OpenAM for Authentication==<br />
CTP can be configured to support OpenAM for user authentication. See [[CTP Authentication Using OpenAM]] for details.<br />
<br />
==Upgrading a Tomcat MIRC Site==<br />
To upgrade from the Tomcat MIRC implementation to the CTP MIRC implementation, there are two steps:<br />
* create a fresh installation of CTP MIRC<br />
* copy the existing Tomcat MIRC site to the CTP MIRC site.<br />
<br />
To assist in copying the old site to the new one, the CTP MIRC installation includes a program called <b><tt>Copier.jar</tt></b> in the <b><tt>CTP</tt></b> directory. To run the program, double-click the file or start it with the command:<br />
:<b><tt>java -jar Copier.jar</tt></b><br />
<br />
The <b><tt>Copier</tt></b> program can be run while the Tomcat MIRC site is running. The Tomcat MIRC site is not modified in any way.<br />
<br />
If the <b><tt>Copier</tt></b> program is run while the CTP MIRC site is running, it automatically stops the site.<br />
<br />
The <b><tt>Copier</tt></b> program copies:<br />
* the users' accounts<br />
* the users' names, affiliations, and contact information<br />
* the storage services:<br />
** all the MIRCdocuments<br />
** the settings:<br />
*** Storage Service tagline<br />
*** Author Service enable<br />
*** Submit Service enable<br />
*** Zip Service enable<br />
*** DICOM Service enable<br />
*** TCE Service enable<br />
*** autoindex enable<br />
*** maximum upload size<br />
*** JPEG quality parameter<br />
*** deleted documents timeout<br />
<br />
The following information is <u>not</u> copied:<br />
* the users' file cabinets<br />
* the shared file cabinet<br />
* the users' conferences<br />
* the shared conferences<br />
<br />
Notes: <br />
* If a user already exists in the CTP site, that user is not modified.<br />
* When copying a storage service, the program tries to find an existing storage service with the same name. If it finds one, it adds the documents to the existing storage service. If it does not find one, it creates a new storage service.<br />
* The program can be run multiple times without creating duplicate user accounts, storage services, or MIRCdocuments.<br />
* When the CTP MIRC site is first installed, one empty storage service is automatically provided. After copying from the Tomcat site to the CTP site, this storage service may still be empty. If you want to remove it, go to the Storage Service admin page and click the <b>Remove this Storage Service</b> button.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8054MIRC CTP2019-03-09T00:54:33Z<p>Johnperry: /* ExportService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8053MIRC CTP2019-03-09T00:53:39Z<p>Johnperry: /* Processor */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8052MIRC CTP2019-03-09T00:50:54Z<p>Johnperry: /* PDFStorageService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
See the descriptions of the attributes in the DirectoryStorageService.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8051MIRC CTP2019-03-09T00:49:34Z<p>Johnperry: /* DirectoryStorageService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
=====PDFStorageService=====<br />
The PDFStorageService extracts PDFs from DicomObjects and stores them in a directory structure using exactly the same rules defined for the DirectoryStorageService. The configuration element for the StorageService is:<br />
<pre><br />
<PDFStorageService<br />
name="PDFStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.PDFStorageService"<br />
root="D:/storage/root" <br />
filenameTag=""<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8050MIRC CTP2019-03-09T00:39:18Z<p>Johnperry: /* DicomPaletteImageConverter */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPhotometricInterpretationConverter=====<br />
The DicomPhotometricInterpretationConverter is a processor stage that converts DicomObjects from PhotometricInterpretation YBR_FULL_422 to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPhotometricInterpretationConverter<br />
name="DicomPhotometricInterpretationConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPhotometricInterpretationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPhotometricInterpretationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_CTP_DICOM_Pixel_Anonymizer&diff=8049The CTP DICOM Pixel Anonymizer2018-12-30T20:45:46Z<p>Johnperry: </p>
<hr />
<div>The CTP DicomPixelAnonymizer is a pipeline stage that blanks regions of pixels in a DICOM image. It is configured with a script file that specifies which regions are to be blanked, based on information in the non-pixel part of the DICOM dataset. This article describes the script file and the language in which it is written. The intended audience for this article is CTP administrators setting up a processing pipeline.<br />
<br />
For information on configuring the DicomPixelAnonymizer stage, see [[Using the CTP DicomPixelAnonymizer]].<br />
==The Script File==<br />
The script file is organized into one or more sections, with each section being comprised of a <b>signature</b> and one or more <b>region</b>s. The format of a section is shown below:<br />
<br />
<pre><br />
{ signature }<br />
(region) (region) ... (region)<br />
</pre><br />
<br />
Each signature defines one image type based on a calculation specified in the signature's script. The signature's script is enclosed in braces, <b>{</b> and <b>}</b>. Each region is enclosed in parentheses.<br />
<br />
Any text that is not contained within braces or parentheses is treated as comments. Comments may not contain either braces or parentheses.<br />
<br />
When the DicomPixelAnonymizer receives a DicomObject, it first tests the object to see if it is an image. If it is not an image, it passes the object on without modification.<br />
<br />
If the object is an image, it next determines whether the object contains encapsulated pixel data. Such objects contain compressed images. The DicomPixelAnonymizer only accepts uncompressed images or images compressed with the JPEGBaseline syntax. All other images are passed without modification. Any other objects that are to be processed must first be decompressed by including a [[CTP-The_RSNA_Clinical_Trial_Processor#DicomDecompressor|DicomDecompressor]] stage in the pipeline somewhere before the DicomPixelAnonymizer.<br />
<br />
If the object meets the above criteria, the DicomPixelAnonymizer sequences through the signatures defined in the script file to find a signature that the object matches. The DicomPixelAnonymizer blanks all the regions in the image associated with the first matching signature. When a region is blanked, all the pixels in the region are replaced with zeroes.<br />
<br />
If the object matches no signature in the script file, the object is passed on without modification.<br />
<br />
==The Script Language==<br />
The script language interrogates a DICOM object and computes a boolean result that, if <b>true</b>, is interpreted to be a match for the signature. The language is identical to the one defined for the [[The_CTP_DICOM_Filter|DicomFilter]] pipeline stage.<br />
<br />
==Regions==<br />
A <b>region</b> is a rectangular area of an image, specified by four integers, separated by commas and encapsulated in parentheses. The integers represent:<br />
* the horizontal component of the left side<br />
* the vertical component of the top<br />
* the width<br />
* the height<br />
<br />
The origin of the image's coordinate system is at the upper left corner, with the positive horizontal axis pointing to the right and the positive vertical axis pointing down.<br />
<br />
Note: If the x coordinate of a region is negative, the region is spaced in from the right side of the image. If the y coordinate of a region is negative, the region is spaced up from the bottom of the image. Thus, to blank a 50x60 rectangle spaced 10 pixels up and 10 pixels left of the lower right corner of an image, the region might be (-50,-60,40,50).<br />
<br />
==Example==<br />
The following simple example shows the definition of regions for two different manufacturers' CT products. <br />
<br />
<pre><br />
{ Modality.equals("CT") <br />
* Manufacturer.containsIgnoreCase("manufacturer1") <br />
* ManufacturerModelName.containsIgnoreCase("modelA") }<br />
(0,0,100,20) (480,200,32,250)<br />
<br />
{ Modality.equals("CT") <br />
* Manufacturer.containsIgnoreCase("manufacturer2") <br />
* ManufacturerModelName.containsIgnoreCase("modelB") }<br />
(400,0,112,20) (0,200,32,250)<br />
</pre><br />
<br />
Note that in a real CT study, one might want to use a more sophisticated test to discriminate, for example, between transaxial images and scout images, assigning different signatures and regions to each.<br />
For modalities which use DICOM element (0028,0301) to indicate that images contain burned-in annotation, one might also include the additional constraint:<br />
<br />
:<tt><b>BurnedInAnnotation.equals("YES")</b></tt></div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP_Articles&diff=8048MIRC CTP Articles2018-12-02T01:39:09Z<p>Johnperry: </p>
<hr />
<div>This is a list of articles on this Wiki related to the RSNA MIRC Clinical Trials Processor (CTP).<br />
<br />
<b>Main Articles</b><br />
<br />
* [[MIRC CTP]] is the top-level article. It describes the installation and configuration of the program.<br />
* [[The CTP Launcher Configuration Editor]] describes how to configure CTP.<br />
* [[Enabling SSL in the CTP Server]] describes how to configure the CTP server for SSL connections<br />
* [[Running CTP as a Windows Service]] describes how to install and configure CTP as a Windows service.<br />
* [[Running CTP as a Linux Service]] describes how to install and configure CTP as a Linux service.<br />
* [[CTP Authentication and Privileges]] describes how CTP authenticates users and provides access to protected functions.<br />
* [[CTP Authentication Using LDAP]] describes how to configure CTP to use an LDAP server for user authentication.<br />
* [[CTP Authentication Using OpenAM]] describes how to configure CTP to use an OpenAM server for user authentication.<br />
* [[Java Advanced Imaging ImageIO Tools]] provides links to the ImageIO Tools on various platforms.<br />
<br />
<b>Data Object Articles</b><br />
* [[The CTP XmlObject]] describes the placement of identifiers in an XmlObject.<br />
* [[The CTP ZipObject]] describes the structure of a ZipObject, including the schema of the manifest.<br />
<br />
<b>Filter Articles</b><br />
* [[The CTP DICOM Filter]] describes the script language for the DicomFilter pipeline stage.<br />
* [[The CTP XML and Zip Filters]] describes the script language for the XmlFilter and ZipFilter pipeline stages.<br />
<br />
<b>Anonymizer Articles</b><br />
* [[The CTP DICOM Anonymizer]] describes the script language and the functions available for anonymization of DICOM objects.<br />
* [[The CTP DICOM Anonymizer Configurator]] describes anonymization profiles and how to use the configurator to edit anonymization scripts.<br />
* [[The DICOM Anonymizer Keep Safe Private Elements Feature]] describes how to extend the index of private elements.<br />
* [[The CTP DICOM Pixel Anonymizer]] describes the script language for modifying the pixels in DICOM objects.<br />
* [[Using the CTP DicomPixelAnonymizer]] explains how to use the stage most effectively.<br />
* [[The CTP XML Anonymizer]] describes the script language and the functions available for anonymization of XML objects and the manifests of Zip objects.<br />
* [[DICOM Anonymizer Configuration for Assigning Subject IDs]] describes the special considerations involved in using the DICOM Anonymizer to create subject IDs.<br />
* [[The CTP Lookup Table Editor]] describes how to add subject IDs to the DICOM Anonymizer lookup table.<br />
* [[The dcm4che Library Documentation]] provides links to tables of DICOM elements and UIDs useful in writing anonymizer and filter scripts.<br />
* [[The_DicomAnonymizerTool]] describes how to use the command-line anonymizer program.<br />
<br />
<b>FileStorageService Articles</b><br />
* [[The CTP FileStorageService Web Server]] describes the web access features of the FileStorageService pipeline stage.<br />
* [[The CTP FileStorageService Access Mechanism]] describes the how access to stored objects can be controlled in the FileStorageService pipeline stage.<br />
<br />
<b>Special Configuration Articles</b><br />
* [[CTP Configuration for Study Distribution]] describes how to use CTP to distribute studies to patients and referring physicians.<br />
* [[CTP Configuration for NBIA]] describes how to configure CTP to serve as the front-end of the NBIA system.<br />
* [[CTP Configuration for the Image Sharing Project]] describes how to configure CTP to interface to the Edge Server.<br />
* [[Configuring the HttpExportService for Connection to XNAT Servers]] describes special features for transfers to XNAT servers.<br />
* [[Using the CTP Application Server]] describes how to launch Java Web Start programs from the CTP Server.<br />
* [[Configuring the CTPClient Application for Clinical Trials]] describes how to configure and launch the CTPClient application.<br />
* [[Using CTPClient]] describes how to use CTPClient to submit studies to clinical trials.<br />
* [[Using the DicomAnonymizer dateinterval Function]] describes special considerations in using the dateinterval function.<br />
* [[Extending the CTP Server Content Type Associations]] describes how to add content type definitions to the CTP Server.<br />
* [[Using the CTP EmailService Pipeline Stage]] describes how to send email notifications of received studies.<br />
* [[Using the CTP AuditLog Plugin]] describes how to use the AuditLog plugin to build tables of element values.<br />
<br />
<b>Articles for Developers and Planners</b><br />
* [[Setting Up a MIRC Development Environment]] describes the development environment that was used to develop all the MIRC software, including CTP.<br />
* [[Extending CTP]] describes how to add new pipeline stages or DatabaseAdapters to CTP.<br />
* [[CTP Plugins]] describes how to develop new plugins.<br />
* [[Developing DICOM Anonymizer Extensions]] describes how to use plugins to extend the DICOM Anonymizer.<br />
* [[Developing a DicomDifferenceLogger LogAdapter]] describes how to interface the DicomDifferenceLogger to an external database.<br />
* [[The Lookup Table Modification API]] describes how an external application can modify the DICOM Anonymizer Lookup Table.<br />
* [[The CTP Module]] describes the contents and theory of operation of the CTP application.<br />
* [[The Util Module]] describes the contents and theory of operation of the utilities used in CTP.<br />
<br />
<b>Deprecated Articles</b><br />
* [[The CTP JarClassLoader]] describes the mechanism that CTP used to load classes before it was changed to allow it to dynamically modify the classpath.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_DicomAnonymizerTool&diff=8047The DicomAnonymizerTool2018-12-02T01:37:41Z<p>Johnperry: </p>
<hr />
<div>The DicomAnonymizerTool is a command-line program that processes a single file or a tree of directories using pipeline stages like those in CTP. It contains a DicomFilter, a DicomPixeAnonymizer, and a DicomAnonymizer. Each of the stages can be enabled, disabled, or configured through command-line parameters.<br />
<br />
The installer for the program can be obtained at http://mirc.rsna.org/download/DicomAnonymizerTool.jar.<br />
<br />
To install the program, run the installer and select a directory. The installer will create a subdirectory called DicomAnonymizerTool in the selected directory and place all the necessary files in it.<br />
<br />
The program runs on Java 7 or better, including Java 9 and 10.<br />
<br />
To run the program, open a command window in the program's directory and run the program from the command line.<br />
<br />
If the program is run with no command-line parameters, it will list help information and information about the configuration of the platform on which it is running:<br />
<br />
<pre><br />
D:\JavaPrograms\DicomAnonymizerTool>java -jar DAT.jar<br />
Usage: java -jar DAT.jar {parameters}<br />
where:<br />
-in {input} specifies the file or directory to be anonymized<br />
If {input} is a directory, all files in it and its subdirectories are processed.<br />
-out {output} specifies the file or directory in which to store the anonymized file or files.<br />
If -out is missing and -in specifies a file, the anonymized file is named {input}-an.<br />
If -out is missing and -in specifies a directory, an output directory named {input}-an is created.<br />
If {output} is missing and -in specifies a file, the anonymized file overwrites {input}<br />
If {output} is present and -in specifies a file, the anonymized file is named {output}<br />
If {output} is present and -in specifies a directory, an output directory named {output} is created.<br />
-f {scriptfile} specifies the filter script.<br />
If -f is missing, all files are accepted.<br />
If {scriptfile} is missing, the default script is used.<br />
-da {scriptfile} specifies the anonymizer script.<br />
If -da is missing, element anonymization is not performed.<br />
If {scriptfile} is missing, the default script is used.<br />
-p{param} "{value}" specifies a value for the specified parameter.<br />
{value} must be encapsulated in quotes.<br />
-e{element} "{script}" specifies a script for the specified element.<br />
{element} may be specified as a DICOM keyword, e.g. -ePatientName.<br />
{element} may be specified as (group,element), e.g. -e(0010,0010).<br />
{element} may be specified as [group,element], e.g. -e[0010,0010].<br />
{element} may be specified as groupelement, e.g. -e00100010.<br />
{script} must be encapsulated in quotes.<br />
-lut {lookuptablefile} specifies the anonymizer lookup table properties file.<br />
If -lut is missing, the default lookup table is used.<br />
-dpa {pixelscriptfile} specifies the pixel anonymizer script file.<br />
If -dpa is missing, pixel anonymization is not performed.<br />
If {pixelscriptfile} is missing, the default pixel script is used.<br />
-dec specifies that the image is to be decompressed if the pixel anonymizer requires it.<br />
-rec specifies that the image is to be recompressed after pixel anonymization if it was decompressed.<br />
-test specifies that the pixel anonymizer is to blank regions in mid-gray.<br />
-check {frame} specifies that the anonymized image is to be tested to ensure that the images load.<br />
If -check is missing, no frame checking is done.<br />
If {frame} is missing, only the last frame is checked.<br />
If {frame} is specified as first, only the first frame is checked.<br />
If {frame} is specified as last, only the last frame is checked.<br />
If {frame} is specified as all, all frames are checked.<br />
-n {threads} specifies the number of parallel threads used for processing.<br />
-v specifies verbose output<br />
<br />
Configuration:<br />
os.name: Windows 10<br />
java.version: 10.0.1<br />
sun.arch.data.model: 64<br />
java.home: C:\Program Files\Java\jre-10.0.1<br />
clib: D:\JavaPrograms\DicomAnonymizerTool\clibwrapper_jiio-1.2-pre-dr-b04.jar<br />
jai: D:\JavaPrograms\DicomAnonymizerTool\jai_imageio-1.2-pre-dr-b04.jar<br />
jiio: null<br />
jiio sse2: null<br />
jiio util: null<br />
ImageIO Tools version: 1.2-pre-dr-b04<br />
<br />
This Java does not have the ImageIOTools native code extensions installed.<br />
<br />
Available codecs:<br />
R/W BMP<br />
R/W DICOM<br />
R/W GIF<br />
R/W JPEG<br />
R/W JPEG2000<br />
R/W JPG<br />
R/W PCX<br />
R/W PNG<br />
R/W PNM<br />
R/W RAW<br />
R RLE<br />
R/W TIFF<br />
R/W WBMP<br />
</pre><br />
<br />
All the default script files are contained in the same directory as the DAT.jar file. The defaults can be edited with any text editor, but changes will be overwritten during an upgrade. If specialized scripts are required, it is best to create new files for them and specify the script files in the appropriate program parameters.<br />
<br />
In special situations where one or more AnonymizerExtensions are required, a config.xml file must be put in the directory to specify the plugins. An example file might be:<br />
<br />
<pre><br />
<Configuration><br />
<Plugin<br />
baseDate="20000101"<br />
class="edu.emory.anonymizer.AnonymizerDateExtension"<br />
dateTableFile="D:/Data/Emory/testzip/testzip/TimeOfInjury.csv"<br />
id="ADEID"<br />
name="AnonymizerDateExtension"<br />
root="test/AnonymizerDateExtension"/><br />
</Configuration><br />
</pre><br />
<br />
When a config.xml file is found, it is loaded in the same way the CTP config.xml file is loaded, so there will be quite a bit of additional logging in the command window before file processing starts.<br />
<br />
IMPORTANT: For technical reasons, any AnonymizerExtension plugins must be contained in files with the names extensions1.jar, extensions2.jar, and/or extensions3.jar. No other extensions jars are loaded by the program. A single extensions jar file can contain many AnonymizerExtensions.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_DicomAnonymizerTool&diff=8046The DicomAnonymizerTool2018-12-02T01:33:39Z<p>Johnperry: </p>
<hr />
<div>The DicomAnonymizerTool is a command-line program that processes a single file or a tree of directories using pipeline stages like those in CTP. It contains a DicomFilter, a DicomPixeAnonymizer, and a DicomAnonymizer. Each of the stages can be enabled, disabled, or configured through command-line parameters.<br />
<br />
The installer for the program can be obtained at http://mirc.rsna.org/download/DicomAnonymizerTool.jar.<br />
<br />
To install the program, run the installer and select a directory. The installer will create a subdirectory called DicomAnonymizerTool in the selected directory and place all the necessary files in it.<br />
<br />
The program runs on Java 7 or better, including Java 9 and 10.<br />
<br />
To run the program, open a command window in the program's directory and run the program from the command line.<br />
<br />
If the program is run with no command-line parameters, it will list help information and information about the configuration of the platform on which it is running:<br />
<br />
<pre><br />
D:\JavaPrograms\DicomAnonymizerTool>java -jar DAT.jar<br />
Usage: java -jar DAT.jar {parameters}<br />
where:<br />
-in {input} specifies the file or directory to be anonymized<br />
If {input} is a directory, all files in it and its subdirectories are processed.<br />
-out {output} specifies the file or directory in which to store the anonymized file or files.<br />
If -out is missing and -in specifies a file, the anonymized file is named {input}-an.<br />
If -out is missing and -in specifies a directory, an output directory named {input}-an is created.<br />
If {output} is missing and -in specifies a file, the anonymized file overwrites {input}<br />
If {output} is present and -in specifies a file, the anonymized file is named {output}<br />
If {output} is present and -in specifies a directory, an output directory named {output} is created.<br />
-f {scriptfile} specifies the filter script.<br />
If -f is missing, all files are accepted.<br />
If {scriptfile} is missing, the default script is used.<br />
-da {scriptfile} specifies the anonymizer script.<br />
If -da is missing, element anonymization is not performed.<br />
If {scriptfile} is missing, the default script is used.<br />
-p{param} "{value}" specifies a value for the specified parameter.<br />
{value} must be encapsulated in quotes.<br />
-e{element} "{script}" specifies a script for the specified element.<br />
{element} may be specified as a DICOM keyword, e.g. -ePatientName.<br />
{element} may be specified as (group,element), e.g. -e(0010,0010).<br />
{element} may be specified as [group,element], e.g. -e[0010,0010].<br />
{element} may be specified as groupelement, e.g. -e00100010.<br />
{script} must be encapsulated in quotes.<br />
-lut {lookuptablefile} specifies the anonymizer lookup table properties file.<br />
If -lut is missing, the default lookup table is used.<br />
-dpa {pixelscriptfile} specifies the pixel anonymizer script file.<br />
If -dpa is missing, pixel anonymization is not performed.<br />
If {pixelscriptfile} is missing, the default pixel script is used.<br />
-dec specifies that the image is to be decompressed if the pixel anonymizer requires it.<br />
-rec specifies that the image is to be recompressed after pixel anonymization if it was decompressed.<br />
-test specifies that the pixel anonymizer is to blank regions in mid-gray.<br />
-check {frame} specifies that the anonymized image is to be tested to ensure that the images load.<br />
If -check is missing, no frame checking is done.<br />
If {frame} is missing, only the last frame is checked.<br />
If {frame} is specified as first, only the first frame is checked.<br />
If {frame} is specified as last, only the last frame is checked.<br />
If {frame} is specified as all, all frames are checked.<br />
-n {threads} specifies the number of parallel threads used for processing.<br />
-v specifies verbose output<br />
<br />
Configuration:<br />
os.name: Windows 10<br />
java.version: 10.0.1<br />
sun.arch.data.model: 64<br />
java.home: C:\Program Files\Java\jre-10.0.1<br />
clib: D:\JavaPrograms\DicomAnonymizerTool\clibwrapper_jiio-1.2-pre-dr-b04.jar<br />
jai: D:\JavaPrograms\DicomAnonymizerTool\jai_imageio-1.2-pre-dr-b04.jar<br />
jiio: null<br />
jiio sse2: null<br />
jiio util: null<br />
ImageIO Tools version: 1.2-pre-dr-b04<br />
<br />
This Java does not have the ImageIOTools native code extensions installed.<br />
<br />
Available codecs:<br />
R/W BMP<br />
R/W DICOM<br />
R/W GIF<br />
R/W JPEG<br />
R/W JPEG2000<br />
R/W JPG<br />
R/W PCX<br />
R/W PNG<br />
R/W PNM<br />
R/W RAW<br />
R RLE<br />
R/W TIFF<br />
R/W WBMP<br />
</pre><br />
<br />
All the default script files are contained in the same directory as the DAT.jar file. The defaults can be edited with any text editor, but changes will be overwritten during an upgrade. If specialized scripts are required, it is best to create new files for them and specify the script files in the appropriate program parameters.<br />
<br />
In special situations where one or more AnonymizerExtensions are required, a config.xml file must be put in the directory to specify the plugins. An example file might be:<br />
<br />
<pre><br />
<Configuration><br />
<Plugin<br />
baseDate="20000101"<br />
class="edu.emory.anonymizer.AnonymizerDateExtension"<br />
dateTableFile="D:/Data/Emory/testzip/testzip/TimeOfInjury.csv"<br />
id="ADEID"<br />
name="AnonymizerDateExtension"<br />
root="test/AnonymizerDateExtension"/><br />
</Configuration><br />
</pre><br />
<br />
When a config.xml file is found, it is loaded in the same way the CTP config.xml file is loaded, so there will be quite a bit of additional logging in the command window before file processing starts.<br />
<br />
IMPORTANT: For technical reasons, any AnonymizerExtension plugins must be contained in files with the names extension1.jar, extension2.jar, and/or extension3.jar. No other extension jars are loaded by the program. A single jar file can contain many AnonymizerExtensions.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_DicomAnonymizerTool&diff=8045The DicomAnonymizerTool2018-12-02T01:13:19Z<p>Johnperry: Created page with "The DicomAnonymizerTool is a command-line program that processes a single file or a tree of directories using pipeline stages like those in CTP. It contains a DicomFilter, a D..."</p>
<hr />
<div>The DicomAnonymizerTool is a command-line program that processes a single file or a tree of directories using pipeline stages like those in CTP. It contains a DicomFilter, a DicomPixeAnonymizer, and a DicomAnonymizer. Each of the stages can be enabled, disabled, or configured through command-line parameters.<br />
<br />
The installer for the program can be obtained at http://mirc.rsna.org/download/DicomAnonymizerTool.jar.<br />
<br />
To install the program, run the installer and select a directory. The installer will create a subdirectory called DicomAnonymizerTool in the selected directory and place all the necessary files in it.<br />
<br />
The program runs on Java 7 or better, including Java 9 and 10.<br />
<br />
To run the program, open a command window in the program's directory and run the program from the command line.<br />
<br />
If the program is run with no command-line parameters, it will list help information and information about the configuration of the platform on which it is running:<br />
<br />
<pre><br />
D:\JavaPrograms\DicomAnonymizerTool>java -jar DAT.jar<br />
Usage: java -jar DAT.jar {parameters}<br />
where:<br />
-in {input} specifies the file or directory to be anonymized<br />
If {input} is a directory, all files in it and its subdirectories are processed.<br />
-out {output} specifies the file or directory in which to store the anonymized file or files.<br />
If -out is missing and -in specifies a file, the anonymized file is named {input}-an.<br />
If -out is missing and -in specifies a directory, an output directory named {input}-an is created.<br />
If {output} is missing and -in specifies a file, the anonymized file overwrites {input}<br />
If {output} is present and -in specifies a file, the anonymized file is named {output}<br />
If {output} is present and -in specifies a directory, an output directory named {output} is created.<br />
-f {scriptfile} specifies the filter script.<br />
If -f is missing, all files are accepted.<br />
If {scriptfile} is missing, the default script is used.<br />
-da {scriptfile} specifies the anonymizer script.<br />
If -da is missing, element anonymization is not performed.<br />
If {scriptfile} is missing, the default script is used.<br />
-p{param} "{value}" specifies a value for the specified parameter.<br />
{value} must be encapsulated in quotes.<br />
-e{element} "{script}" specifies a script for the specified element.<br />
{element} may be specified as a DICOM keyword, e.g. -ePatientName.<br />
{element} may be specified as (group,element), e.g. -e(0010,0010).<br />
{element} may be specified as [group,element], e.g. -e[0010,0010].<br />
{element} may be specified as groupelement, e.g. -e00100010.<br />
{script} must be encapsulated in quotes.<br />
-lut {lookuptablefile} specifies the anonymizer lookup table properties file.<br />
If -lut is missing, the default lookup table is used.<br />
-dpa {pixelscriptfile} specifies the pixel anonymizer script file.<br />
If -dpa is missing, pixel anonymization is not performed.<br />
If {pixelscriptfile} is missing, the default pixel script is used.<br />
-dec specifies that the image is to be decompressed if the pixel anonymizer requires it.<br />
-rec specifies that the image is to be recompressed after pixel anonymization if it was decompressed.<br />
-test specifies that the pixel anonymizer is to blank regions in mid-gray.<br />
-check {frame} specifies that the anonymized image is to be tested to ensure that the images load.<br />
If -check is missing, no frame checking is done.<br />
If {frame} is missing, only the last frame is checked.<br />
If {frame} is specified as first, only the first frame is checked.<br />
If {frame} is specified as last, only the last frame is checked.<br />
If {frame} is specified as all, all frames are checked.<br />
-n {threads} specifies the number of parallel threads used for processing.<br />
-v specifies verbose output<br />
<br />
Configuration:<br />
os.name: Windows 10<br />
java.version: 10.0.1<br />
sun.arch.data.model: 64<br />
java.home: C:\Program Files\Java\jre-10.0.1<br />
clib: D:\JavaPrograms\DicomAnonymizerTool\clibwrapper_jiio-1.2-pre-dr-b04.jar<br />
jai: D:\JavaPrograms\DicomAnonymizerTool\jai_imageio-1.2-pre-dr-b04.jar<br />
jiio: null<br />
jiio sse2: null<br />
jiio util: null<br />
ImageIO Tools version: 1.2-pre-dr-b04<br />
<br />
This Java does not have the ImageIOTools native code extensions installed.<br />
<br />
Available codecs:<br />
R/W BMP<br />
R/W DICOM<br />
R/W GIF<br />
R/W JPEG<br />
R/W JPEG2000<br />
R/W JPG<br />
R/W PCX<br />
R/W PNG<br />
R/W PNM<br />
R/W RAW<br />
R RLE<br />
R/W TIFF<br />
R/W WBMP<br />
</pre></div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8044MIRC CTP2018-11-20T14:30:26Z<p>Johnperry: /* PollingHttpImportService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http[s]://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8043MIRC CTP2018-11-20T14:30:00Z<p>Johnperry: /* PollingHttpImportService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port/context"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService. The protocol of the URL must correspond to the protocol (http or https) of the PolledHttpExportService, and the context must be the same as the id attribute of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8042MIRC CTP2018-11-20T14:26:50Z<p>Johnperry: /* PolledHttpExportService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
ssl="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>ssl</b> determines whether the server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8041MIRC CTP2018-11-20T14:24:26Z<p>Johnperry: /* PolledHttpExportService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any single-word text to be used to uniquely identify the stage. The id value is used as the servlet context by which the PollingHttpImportService accesses the export queue, so this attribute is required.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=Configuring_the_HttpExportService_for_Connection_to_XNAT_Servers&diff=8040Configuring the HttpExportService for Connection to XNAT Servers2018-07-16T20:55:27Z<p>Johnperry: </p>
<hr />
<div>This article describes how to configure the CTP HttpExportService pipeline stage for efficient export to an XNAT server. The intended audience for this article is CTP administrators.<br />
<br />
The HttpExportService configuration element has two child elements intended to invoke special features in coordination with an XNAT server. The Launcher application's Configuration tab allows the administrator to add these children and provides guidance in defining their attributes.<br />
<br />
The <b><tt>xnat</tt></b> child element makes authentication of the transfers from the HttpExportService to the XNAT server more efficient. The element has these attributes:<br />
<br />
<pre><br />
<xnat<br />
url="https://host:port/data/JSESSION"<br />
cookieName="JSESSIONID"<br />
password=""<br />
username=""/><br />
</pre><br />
<br />
*<b><tt>url</tt></b> specifies the URL of the XNAT server's authentication service.<br />
*<b><tt>cookieName</tt></b> specifies the cookie name in the set-cookie header returned by the XNAT server after a successful authentication.<br />
*<b><tt>username</tt></b> specifies the username on the XNAT server for authentication.<br />
*<b><tt>password</tt></b> specifies the password on the XNAT server for authentication.<br />
<br />
Notes:<br />
# In the <b><tt>url</tt></b> attribute, JSESSION is the only value recognized by the current XNAT implementation. Do not change this unless the XNAT API changes.<br />
# In the <b><tt>cookieName</tt></b> attribute, JSESSIONID is the only value recognized by the current XNAT implementation. Do not change this unless the XNAT API changes.<br />
<br />
When this element is present, the HttpExportService authenticates on the first transfer, obtains the session cookie, and passes that cookie back to the server on all subsequent transfers. The effect is to reduce the authentication load on the XNAT server dramatically and to reduce the number of parallel threads in the server required to handle large transfers.<br />
<br />
The <b><tt>compressor</tt></b> child element makes the actual file transfers themselves more efficient. The element has these attributes:<br />
<br />
<pre><br />
<compressor<br />
cacheSize="0"<br />
structure="dir1/dir2/dir3/.../name"<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"/><br />
</pre><br />
<br />
*<b><tt>cacheSize</tt></b> specifies the maximum number of files to combine into a single zip file for transmission to the XNAT server. The default is zero, meaning no zip compression. A value of 100 has been found to work well.<br />
*<b>structure</b> is text specifying the hierarchy of the storage tree in the zip file, ending in a file name. For XNAT transfers, the directory hierarchy is generally omitted and the attribute simply specifies the construction of the file name, resulting in all the files being stored in the root of the zip file. If a more complex structure is required, path elements are separated by slashes. Each path element in the sequence can consist of text and/or DICOM tags. If a path element in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current DICOM object are substituted for the tags. See the notes below for more details and examples of structure attributes. If this attribute is missing, all files are stored in the root directory of the zip file and given the name specified by the defaultString attribute, e.g. UNKNOWN[n].dcm, where n is a number.<br />
*<b><tt>defaultString</tt></b> specifies the text to be used when a DICOM element specified in the structure attribute is missing from a file to be transferred.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name constructed froom the structure attribute. If this attribute is missing, the underscore character is used.<br />
<br />
Notes:<br />
# In path elements, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
When this element present and cacheSize is greater than zero, the compressor attempts to group as many files as are available (up to cacheSize) into a single zip file and initiates a single transfer. The compressor never waits for more files if fewer than cacheSize files are available; it just sends all that it has. The XNAT server automatically de-compresses the zip file and stores the content files.<br />
<br />
This is an example of an HttpExportService configuration element exporting to an XNAT server:<br />
<br />
<pre><br />
<HttpExportService<br />
acceptXmlObjects="no"<br />
acceptZipObjects="no"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
name="HTTPS Export to XNAT"<br />
quarantine="/data/test/quarantines/dicom-export"<br />
root="/data/test/dicom-export"<br />
sendDigestHeader="yes"<br />
url="https://XNAT-IP-address:443/data/services/import?import-handler=DICOM-zip&amp;inbody=true"><br />
<br />
<compressor<br />
cacheSize="100"<br />
defaultString="unknown"<br />
structure="(0010,0020).(0008,0060).(0008,0020).(0008,0030).(0020,0011).(0020,0013).(0019,10A2)"/><br />
<br />
<xnat<br />
cookieName="JSESSIONID"<br />
password="aXNATPassword"<br />
url="https://XNAT-IP-address:443/data/JSESSION"<br />
username="aXNATUser"/><br />
<br />
</HttpExportService><br />
</pre></div>Johnperryhttp://mircwiki.rsna.org/index.php?title=Configuring_the_CTPClient_Application_for_Clinical_Trials&diff=8039Configuring the CTPClient Application for Clinical Trials2018-07-16T20:52:06Z<p>Johnperry: /* Export Service Parameters */</p>
<hr />
<div>The CTPClient application is a program for anonymizing images and transmitting them from image acquisition sites to principal investigator sites in clinical trials. This article describes how to configure, distribute, and run the program. The intended audience for this article is clinical trial administrators and their software minions.<br />
<br />
==Running CTPClient==<br />
CTPClient can be launched via the Java webstart mechanism, thus removing the necessity for installing CTP applications at the image acquisition sites. When run via webstart, the user accesses a URL on the principal investigator's CTP site, and the browser downloads CTPClient and starts it. The recommended method for launching CTPClient via webstart is to use the CTP Application Server on the CTP site. For general information on the Application Server, see [[Using the CTP Application Server]].<br />
<br />
CTPClient can also be launched as a stand-alone application installed on the client computer. When run stand-alone, the program is started by double-clicking the program's icon or by launching a command window and entering the command:<br />
<br />
:<b><tt>java -jar CTPClient.jar [options]</tt></b><br />
<br />
where [options] is a series of quoted parameters, each in the form:<br />
<br />
:<b><tt>"param=value"</tt></b><br />
<br />
==The Processing Pipeline==<br />
===Import Services===<br />
CTPClient has two import mechanisms.<br />
* Locally stored files can be manually selected.<br />
* A DICOM Storage SCP can be enabled to receive files from PACS systems or workstations.<br />
<br />
===Processing Stages===<br />
CTPClient has a fixed processing pipeline consisting of these stages, in this order:<br />
* DicomFilter<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomAnonymizer<br />
<br />
The DicomFilter and DicomPixelAnonymizer stages must be explicitly enabled using the parameters described in the next section. The DicomDecompressor stage is run <u>only if</u> the object being processed matches a signature of the DicomPixelAnonymizer; otherwise, the object is not decompressed. See [[The CTP DICOM Pixel Anonymizer]] for more information.<br />
<br />
The DicomAnonymizer is always enabled.<br />
<br />
No default script is provided for the DicomFilter.<br />
<br />
Default scripts are provided for the DicomPixelAnonymizer and the DicomAnonymizer. <br />
<br />
No default lookup table is provided for the DicomAnonymizer.<br />
<br />
===ExportServices===<br />
CTPClient has four export services:<br />
* HttpExportService<br />
* DicomExportService<br />
* STOWRSExportService<br />
* DirectoryStorageService<br />
<br />
==Run-time Configuration==<br />
CTPClient is designed to be configured by setting the [options] parameters for the transmitting site. When run via webstart, these parameters can be supplied by query parameters in the URL, as in this example:<br />
<br />
:<b><tt>http://ctp.university.edu/webstart/CTPClient?param1=value1&param2=value2</tt></b><br />
<br />
Note that when a value includes whitespace or any other characters that are illegal in a URL, the value must be URL-encoded.<br />
<br />
As mentioned in [[#Building CTPClient|Building CTPClient]], below, a special CTPClient build can be created for specific applications, including application-specific files and configuration parameters.<br />
<br />
===Configuration Parameters===<br />
The parameters supported by the program are shown below.<br />
<br />
====Window Display Parameters====<br />
*<b><tt><font size=4>windowTitle</font></tt></b>: The text to be shown in the title bar of the CTP Client window. The default is "CTP Client".<br />
*<b><tt><font size=4>panelTitle</font></tt></b>: The text to be shown at the top of the main pane in the CTPClient UI. The default is "CTP Client".<br />
*<b><tt><font size=4>helpURL</font></tt></b>: The URL to be accessed when the user clicks the Help button on the CTPClient UI. If this parameter is missing, the Help button is not displayed.<br />
<br />
====Import Service Parameters====<br />
*<b><tt><font size=4>showBrowseButton</font></tt></b>: Specifies whether to display a button allowing the user to browse the local disk for images to display. If an scpPort is defined and the showBrowseButton parameter is set to "no", a browse button is not displayed. If the parameter is set to any other value, the dialog button is displayed, whether an scpPort parameter is supplied or not. <br />
*<b><tt><font size=4>scpPort</font></tt></b>: The port on which CTPClient is to start a DICOM Storage SCP to receive objects via the DICOM protocol. If set to any integer greater than zero, CTPClient starts the SCP and accepts transfers from DICOM Storage SCUs. If the parameter is not supplied, or if it is blank or a non-integer value, the SCP is disabled. The default configuration does not enable the SCP.<br />
*<b><tt><font size=4>acceptNonImageObjects</font></tt></b>: Specifies whether non-image objects are to be selected for processing. If set to "yes", all objects are accepted. If set to any other value, only images are accepted. The default configuration only accepts image objects.<br />
*<b><tt><font size=4>dialogEnabled</font></tt></b>: Specifies whether to provide a dialog for entry of parameters at runtime. If set to "yes", a dialog is constructed from definitions in an XML file. If set to any other value, no dialog is provided.<br />
*<b><tt><font size=4>dialogName</font></tt></b>: The name of an XML file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. If the file is not found on the server, CTPClient looks for the file in the same directory in which the program is running. If that fails, CTPClient looks for the default dialog file built into the application (<b><tt>DIALOG.xml</tt></b>). If the XML file cannot be found, the dialog is disabled, even if the dialogEnabled parameter is set to "yes". Values provided by the user in the dialog are treated as if they were options included in the start command of the program. {See [[#The Dialog XML Schema|The Dialog XML Schema]] for a description of how to configure the dialog.) <br />
*<b><tt><font size=4>showDialogButton</font></tt></b>: Specifies whether to display a button allowing the user to display the dialog. If set to "no", a dialog button is not displayed. If set to any other value, the dialog button is displayed.<br />
<br />
====Processing Pipeline Parameters====<br />
*<b><tt><font size=4>dfEnabled</font></tt></b>: Specifies whether to use the DicomFilter to select objects for processing. If set to "yes", objects are selected using the DicomFilter script. If set to any other value, no filtering is done.<br />
*<b><tt><font size=4>dfScriptName</font></tt></b>: The name of a DicomFilter script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient looks for the default script (<b><tt>DF.script</tt></b>) built into the application. If no default script is found, the DicomFilter stage is disabled, even if the dfEnabled parameter is set to "yes".<br />
*<b><tt><font size=4>dpaEnabled</font></tt></b>: Specifies whether the DicomPixelAnonymizer is to be included in the processing of objects. If set to "yes", objects are processed using the DicomPixelAnonymizer script. If set to any other value, no pixel anonymization is done.<br />
*<b><tt><font size=4>dpaScriptName</font></tt></b>: The name of a DicomPixelAnonymizer script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient looks for the default script (<b><tt>DPA.script</tt></b>) built into the application. If no default script is found, the DicomPixelAnonymizer stage is disabled, even if the dpaEnabled parameter is set to "yes".<br />
*<b><tt><font size=4>setBurnedInAnnotation</font></tt></b>: Specifies whether the BurnedInAnnotation element is to be set to "NO" for DICOM objects that match a DicomPixelAnonymizer signature. If set to "yes", the element value is set, if the parameter is missing or has any other value, the element is not modified. <br />
*<b><tt><font size=4>daScriptName</font></tt></b>: The name of a DicomAnonymizer script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient uses the default script (<b><tt>DA.script</tt></b>) built into the application.<br />
*<b><tt><font size=4>daLUTName</font></tt></b>: The name of a DicomAnonymizer lookup table file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the lookup table file from the server. When not present, CTPClient looks for the default lookup table (<b><tt>LUT.properties</tt></b>) built into the application. If no lookup table is available, an empty lookup table is provided.<br />
<br />
In addition to the standard parameters above, CTPClient supports special parameters for modifying the DicomAnonymizer script parameters and lookup table entries. <br />
<br />
Any parameter name starting with the at-sign ( '@' ) is treated as an anonymizer script modification. The '@' is removed, and the rest of the parameter name is used as the name of a script PARAM. The parameter value (the text after the '=' character) is used as the value for that PARAM. The intent of this feature is to allow a standard script to be tailored for a specific image acquisition site. Note that this feature does not allow element scripts to be modified; it only allows script PARAM values to be changed.<br />
<br />
Any parameter name starting with the dollar-sign ( '$' ) is treated as a lookup table modification. The '$' is removed, and the rest of the parameter name is used as the lookup table key. The parameter value (the text after the '=' character) is used as the value for that key. The intent of this feature is to allow a standard lookup table to be tailored for a specific image acquisition site.<br />
<br />
For more information on anonymizer parameters and lookup tables, see [[The CTP DICOM Anonymizer]], [[The CTP DICOM Anonymizer Configurator]], and [[The CTP Lookup Table Editor]].<br />
<br />
====Export Service Parameters====<br />
*<b><tt><font size=4>httpURL</font></tt></b>: The URL of the destination HttpImportService. If this parameter is not supplied, or if it is blank, the HttpExportService is disabled. This parameter must be a complete URL, including the protocol (http://IP:port or https://IP:port).<br />
*<b><tt><font size=4>showURL</font></tt></b>: "yes" to display a UI field for entering the URL of the destination HttpImportService. "no" to suppress the UI field, thus forcing the URL to be the value of the <b><tt>httpURL</tt></b> parameter. The default value is "yes".<br />
*<b><tt><font size=4>zip</font></tt></b>: "yes" to zip files before transmission via HTTP. The default value is "no". This feature is intended only for transmissions to a CTP site with an HttpImportService configured with a zip parameter set to "yes".<br />
*<b><tt><font size=4>xnatAuthURL</font></tt></b>: The URL of the XNAT server's authentication service. If this parameter is not supplied, or if it is blank, no authentication is performed, and the XNAT session cookie is not supplied in transfers. This parameter must be a complete URL, including the protocol (e.g. http://IP:port/data/JSESSION).<br />
*<b><tt><font size=4>xnatUsername</font></tt></b>: The username for authentication on the XNAT server.<br />
*<b><tt><font size=4>xnatPassword</font></tt></b>: The password for authentication on the XNAT server.<br />
*<b><tt><font size=4>xnatCookiename</font></tt></b>: The session cookie name used by the XNAT server. If this parameter is missing, the default name "JSESSIONID" is supplied.<br />
*<b><tt><font size=4>dicomURL</font></tt></b>: The URL of the destination DICOM Storage SCP (e.g. PACS or workstation). If this parameter is not supplied, or if it is blank, the DicomExportService is disabled. This parameter must be a complete URL, including the protocol (e.g. dicom://CalledAET:CallingAET@IP:port).<br />
*<b><tt><font size=4>stowURL</font></tt></b>: The URL of the destination DICOM STOW-RS Service. If this parameter is not supplied, or if it is blank, the DicomSTOWRSExportService is disabled. This parameter must be a complete URL, including the protocol (e.g. http://ip:port).<br />
*<b><tt><font size=4>stowUsername</font></tt></b>: The username to be used when authenticating with the destination DICOM STOW-RS Service. If this parameter is not supplied, or if it is blank, authentication credentials are not supplied when transferring to the destination system.<br />
*<b><tt><font size=4>stowPassword</font></tt></b>: The password to be used when authenticating with the destination DICOM STOW-RS Service.<br />
*<b><tt><font size=4>exportDirectory</font></tt></b>: The path to a directory in which processed files are to be stored. Files are stored with names constructed from their SOPInstanceUIDs. If this parameter is not supplied, or if it is blank, the DirectoryStorageService is disabled.<br />
*<b><tt><font size=4>renameFiles</font></tt></b>: Whether to rename exported files in the form Study_Series_Acquisition_Instance.dcm. If this parameter is not supplied, or if its value is not "yes", files are named by their SOPInstanceUID values.<br />
<br />
Note: If CTPClient is configured to export to an HTTP destination that requires authentication, the credentials can be included in the httpURL parameter like this: http://username:password@IPAddress:port. If the credentials are omitted from the URL and the destination requires them, CTPClient displays a dialog allowing the user to enter the credentials at the time of transmission.<br />
<br />
====Webstart Parameters====<br />
The Application Server supplies three parameters automatically when starting CTPClient. These are used by CTPClient to contact the server when the <b><tt>dfScriptName</tt></b>, <b><tt>dpaScriptName</tt></b>, <b><tt>daScriptName</tt></b>, or <b><tt>daLUTName</tt></b> parameters are supplied. If CTPClient is not started via webstart and the project requires that files be obtained from a server, the three parameters below must be supplied explicitly.<br />
<br />
*<b><tt><font size=4>protocol</font></tt></b>: The protocol to be used for communication with the CTP site's web server.<br />
*<b><tt><font size=4>host</font></tt></b>: The host IP address or domain name (and port) of the CTP site's web server.<br />
*<b><tt><font size=4>application</font></tt></b>: The name of the application ("<b><tt>CTPClient</tt></b>").<br />
<br />
====Debugging Parameters====<br />
When processing very large (typically multi-frame) objects, it may be necessary to allocate more than the default memory to the application using the <b><tt>max-heap-size</tt></b> attribute described in [[Using the CTP Application Server]]. To make it easy to see how much memory is in use, a button can be displayed in the application's window footer bar by enabling the <b><tt>showMemory</tt></b> parameter.<br />
*<b><tt><font size=4>showMemory</font></tt></b>: "yes" to display the button. The default is "no".<br />
<br />
===Default Configuration===<br />
====Webstart====<br />
For CTPClient instances that are run via Java webstart, it is possible to predefine parameter values in the <tt><b>CTPClient.xsl</b></tt> file stored on the server. This file will be located under the <tt><b>CTP/ROOT</b></tt> directory, typically in a first-generation child called CTPClient, although it is possible to locate it at a lower level, as in <tt><b>CTP/ROOT/MyTrial/CTPClient</b></tt>. The standard <tt><b>CTPClient.xsl</b></tt> file looks like this:<br />
<br />
<pre><br />
<?xml version="1.0" encoding="iso-8859-1"?><br />
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><br />
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" /><br />
<br />
<xsl:template match="/jnlp"><br />
<jnlp<br />
codebase="{environment/protocol}://{environment/host}/{environment/application}" ><br />
<!-- href="{environment/application}.jnlp" > --><br />
<br />
<information><br />
<title>CTP Client Utility</title><br />
<vendor>RSNA</vendor><br />
<homepage href="http://mircwiki.rsna.org/index.php?title=CTP-The_RSNA_Clinical_Trial_Processor"/><br />
<description>CTP Client Utility</description><br />
<description kind="short">Java Web Start program for transmitting data to CTP for clinical trials.</description><br />
<!-- <offline-allowed/> --><br />
</information><br />
<br />
<security><br />
<all-permissions/><br />
</security><br />
<br />
<resources><br />
<j2se version="1.6+"/><br />
<jar href="CTPClient.jar"/><br />
<jar href="CTP.jar"/><br />
<jar href="dcm4che.jar"/><br />
<jar href="dcm4che-imageio-rle-2.0.25.jar"/><br />
<jar href="jdbm.jar"/><br />
<jar href="log4j.jar"/><br />
<jar href="util.jar"/><br />
</resources><br />
<br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</jnlp><br />
</xsl:template><br />
<br />
<xsl:template match="param"><br />
<argument>"<xsl:value-of select="."/>"</argument><br />
</xsl:template><br />
<br />
</xsl:stylesheet><br />
</pre><br />
<br />
To predefine parameters, add <tt><b>argument</b></tt> elements to the <tt><b>application-desc</b></tt> element like this:<br />
<br />
<pre><br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<argument>"name1=value1"</argument><br />
<argument>"name2=value2"</argument><br />
<argument>"name3=value3"</argument><br />
...etc...<br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</pre><br />
<br />
For example:<br />
<br />
<pre><br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<argument>"panelTitle=My Trial CTP Client"</argument><br />
<argument>"showBrowseButton=yes"</argument><br />
<argument>"dialogName=DIALOG.xml"</argument><br />
<argument>"httpURL=http://theURL:80"</argument><br />
<argument>"showURL=yes"</argument><br />
<argument>"daScriptName=CTPClient.script"</argument><br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</pre><br />
<br />
Note that by placing the predefined parameters before the <tt><b>xsl:apply-templates</b></tt> instruction, any parameters that are included in the URL itself will override the defaults.<br />
<br />
====Local====<br />
For CTPClient instances that are installed locally, it is possible to predefine parameter values in a properties file. The file must be called <tt><b>config.default</b></tt>, and it must be stored in the same directory as CTPClient.jar. Here is an example:<br />
<br />
<pre><br />
windowTitle=My Trial<br />
PanelTitle=My Trial<br />
helpURL=http://ctp.myUniversity.edu/myTrial/help.html<br />
dialogEnabled=yes<br />
dialogName=myTrialDialog.xml<br />
showDialogButton=no<br />
dfEnabled=no<br />
dpaEnabled=yes<br />
daScriptName=myTrialDAScript.script<br />
httpURL=http://ctp.PrincipalInvestigator.org:9999<br />
showURL=no<br />
showBrowseButton=yes<br />
</pre><br />
<br />
Properties files use the backslash character for escaping special characters, so if a backslash character is required in a property, it must be escaped by a backslash. Even on a Windows system, forward slashes work in specifying file paths in property values.<br />
<br />
==The Dialog XML Schema==<br />
When the <b><tt>dialogEnabled</tt></b> parameter is set to "yes", CTPClient loads an XML file to define the contents of a dialog allowing the user to enter values for parameters. The following is an example XML structure specifying three parameters:<br />
<br />
<pre><br />
<dialog title="New Patient" mode="study"><br />
<h>Site Parameters</h><br />
<p><br />
Enter the ID value for this site.<br />
</p><br />
<param<br />
name="@SITEID"<br />
label="Site ID"<br />
value=""/><br />
<h>Patient Parameters</h><br />
<p><br />
Enter the ID and name values for this patient.<br />
</p><br />
<param<br />
name="@SUBJECTID"<br />
label="Subject ID"<br />
value=""/><br />
<param<br />
name="@SUBJECTNAME"<br />
label="Subject Name"<br />
value=""/><br />
</dialog><br />
</pre><br />
<br />
The <b><tt>title</tt></b> attribute of the root element specifies the title of the popup. The title is also used as the name of the button in the main CTPClient window for displaying the dialog, so it should be fairly short.<br />
<br />
The <b><tt>mode</tt></b> attribute of the root element specifies the whether the dialog is to be displayed once for each study transmitted ("study" mode) or once for each click of the Start button ("session" mode). The default is study mode.<br />
<br />
The <b><tt>h</tt></b> element specifies a heading. The element has one optional attribute, <b><tt>align</tt></b>, with allowed values <b><tt>left</tt></b>, <b><tt>center</tt></b>, and <b><tt>right</tt></b>, The default is <b><tt>center</tt></b>.<br />
<br />
The <b><tt>p</tt></b> element specifies a paragraph. Word wrapping is not provided; lines are broken at newline characters. The element has one optional attribute, <b><tt>align</tt></b>, with allowed values <b><tt>left</tt></b>, <b><tt>center</tt></b>, and <b><tt>right</tt></b>, The default is <b><tt>left</tt></b>.<br />
<br />
The <b><tt>param</tt></b> element specifies a parameter whose value is to be entered into the dialog by the user. <br />
* The <b><tt>name</tt></b> attribute specifies the name of an option parameter.<br />
* The <b><tt>label</tt></b> attribute specifies the text to be displayed beside the entry field for the parameter.<br />
* The <b><tt>value</tt></b> attribute specifies the initial value provided in the entry field. If a value was provided by an option parameter when CTPClient was started, that value takes precedence over the value of the <b><tt>value</tt></b> attribute.<br />
<br />
Parameter names starting with <b><tt>@</tt></b> specify PARAM values in DicomAnonymizer scripts.<br />
<br />
Parameter names starting with <b><tt>$</tt></b> specify values in DicomAnonymizer lookup tables.<br />
<br />
The <b><tt>param</tt></b> element has an optional <b><tt>readonly</tt></b> attribute. When set to <b><tt>yes</tt></b>, the entry in the table is not editable. <br />
*If the <b><tt>name</tt></b> attribute is specified and the <b><tt>value</tt></b> attribute is missing or blank, the text displayed is the value of the specified configuration parameter.<br />
*If the <b><tt>value</tt></b> attribute is not blank, it takes precedence over any configuration parameter specified by the <b><tt>name</tt></b> attribute.<br />
*Examples:<br />
<pre><br />
<param<br />
name="@SITEID"<br />
label="Site ID:"<br />
readonly="yes"/><br />
<param<br />
label="Note:"<br />
value="Some readonly text"<br />
readonly="yes"/><br />
</pre><br />
<br />
==Building CTPClient==<br />
In some trials, it may be desired to build a special version of CTPClient with pre-configured values in the configuration files.<br />
<br />
The source code for CTPClient is on GitHub at https://github.com/johnperry/CTPClient.<br />
<br />
The default configuration files are located in the <b><tt>source/files</tt></b> directory:<br />
* <b><tt>config.properties</tt></b><br />
* <b><tt>DPA.script</tt></b><br />
* <b><tt>DA.script</tt></b><br />
<br />
In special situations, default files for the dialog, DicomFilter and DicomAnonymizer lookup table can be provided. The following are the names required by the application:<br />
<br />
* <b><tt>DIALOG.xml</tt></b><br />
* <b><tt>DF.script</tt></b><br />
* <b><tt>LUT.properties</tt></b><br />
<br />
The program is built using <b><tt>ant</tt></b>. After the build is complete, a zip file containing all the files necessary for deployment is located in the <b><tt>products</tt></b> directory.<br />
<br />
==Deploying CTPClient on the CTP Application Server==<br />
As described in [[Using the CTP Application Server]], all the files for CTPClient must be placed in the <b><tt>CTP/ROOT/CTPClient</tt></b> directory. The latest version is encapsulated in a zip file on the RSNA MIRC site at http://mirc.rsna.org/download/CTPClient.zip. <br />
<br />
Included in the zip file is the XSL file required by the Application Server for automatic creation of the webstart <b><tt>jnlp</tt></b> file.<br />
<br />
To deploy CTPClient, create the CTP/ROOT/CTPClient directory and copy all the files from the zip file into it.<br />
<br />
Note: If multiple CTPClient instances are to be supported in one CTP instance, install them in subdirectories of the ROOT directory, like this:<br />
<br />
:ROOT<br />
::TrialX<br />
:::CTPClient<br />
::TrialY<br />
:::CTPClient<br />
::TrialZ<br />
:::CTPClient<br />
<br />
In this situation, the URL to access a trial's CTPClient would include the trial name in the webstart path (e.g. /webstart/TrialY/CTPClient[?params]).</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=Configuring_the_CTPClient_Application_for_Clinical_Trials&diff=8038Configuring the CTPClient Application for Clinical Trials2018-06-30T18:13:25Z<p>Johnperry: /* Export Service Parameters */</p>
<hr />
<div>The CTPClient application is a program for anonymizing images and transmitting them from image acquisition sites to principal investigator sites in clinical trials. This article describes how to configure, distribute, and run the program. The intended audience for this article is clinical trial administrators and their software minions.<br />
<br />
==Running CTPClient==<br />
CTPClient can be launched via the Java webstart mechanism, thus removing the necessity for installing CTP applications at the image acquisition sites. When run via webstart, the user accesses a URL on the principal investigator's CTP site, and the browser downloads CTPClient and starts it. The recommended method for launching CTPClient via webstart is to use the CTP Application Server on the CTP site. For general information on the Application Server, see [[Using the CTP Application Server]].<br />
<br />
CTPClient can also be launched as a stand-alone application installed on the client computer. When run stand-alone, the program is started by double-clicking the program's icon or by launching a command window and entering the command:<br />
<br />
:<b><tt>java -jar CTPClient.jar [options]</tt></b><br />
<br />
where [options] is a series of quoted parameters, each in the form:<br />
<br />
:<b><tt>"param=value"</tt></b><br />
<br />
==The Processing Pipeline==<br />
===Import Services===<br />
CTPClient has two import mechanisms.<br />
* Locally stored files can be manually selected.<br />
* A DICOM Storage SCP can be enabled to receive files from PACS systems or workstations.<br />
<br />
===Processing Stages===<br />
CTPClient has a fixed processing pipeline consisting of these stages, in this order:<br />
* DicomFilter<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomAnonymizer<br />
<br />
The DicomFilter and DicomPixelAnonymizer stages must be explicitly enabled using the parameters described in the next section. The DicomDecompressor stage is run <u>only if</u> the object being processed matches a signature of the DicomPixelAnonymizer; otherwise, the object is not decompressed. See [[The CTP DICOM Pixel Anonymizer]] for more information.<br />
<br />
The DicomAnonymizer is always enabled.<br />
<br />
No default script is provided for the DicomFilter.<br />
<br />
Default scripts are provided for the DicomPixelAnonymizer and the DicomAnonymizer. <br />
<br />
No default lookup table is provided for the DicomAnonymizer.<br />
<br />
===ExportServices===<br />
CTPClient has four export services:<br />
* HttpExportService<br />
* DicomExportService<br />
* STOWRSExportService<br />
* DirectoryStorageService<br />
<br />
==Run-time Configuration==<br />
CTPClient is designed to be configured by setting the [options] parameters for the transmitting site. When run via webstart, these parameters can be supplied by query parameters in the URL, as in this example:<br />
<br />
:<b><tt>http://ctp.university.edu/webstart/CTPClient?param1=value1&param2=value2</tt></b><br />
<br />
Note that when a value includes whitespace or any other characters that are illegal in a URL, the value must be URL-encoded.<br />
<br />
As mentioned in [[#Building CTPClient|Building CTPClient]], below, a special CTPClient build can be created for specific applications, including application-specific files and configuration parameters.<br />
<br />
===Configuration Parameters===<br />
The parameters supported by the program are shown below.<br />
<br />
====Window Display Parameters====<br />
*<b><tt><font size=4>windowTitle</font></tt></b>: The text to be shown in the title bar of the CTP Client window. The default is "CTP Client".<br />
*<b><tt><font size=4>panelTitle</font></tt></b>: The text to be shown at the top of the main pane in the CTPClient UI. The default is "CTP Client".<br />
*<b><tt><font size=4>helpURL</font></tt></b>: The URL to be accessed when the user clicks the Help button on the CTPClient UI. If this parameter is missing, the Help button is not displayed.<br />
<br />
====Import Service Parameters====<br />
*<b><tt><font size=4>showBrowseButton</font></tt></b>: Specifies whether to display a button allowing the user to browse the local disk for images to display. If an scpPort is defined and the showBrowseButton parameter is set to "no", a browse button is not displayed. If the parameter is set to any other value, the dialog button is displayed, whether an scpPort parameter is supplied or not. <br />
*<b><tt><font size=4>scpPort</font></tt></b>: The port on which CTPClient is to start a DICOM Storage SCP to receive objects via the DICOM protocol. If set to any integer greater than zero, CTPClient starts the SCP and accepts transfers from DICOM Storage SCUs. If the parameter is not supplied, or if it is blank or a non-integer value, the SCP is disabled. The default configuration does not enable the SCP.<br />
*<b><tt><font size=4>acceptNonImageObjects</font></tt></b>: Specifies whether non-image objects are to be selected for processing. If set to "yes", all objects are accepted. If set to any other value, only images are accepted. The default configuration only accepts image objects.<br />
*<b><tt><font size=4>dialogEnabled</font></tt></b>: Specifies whether to provide a dialog for entry of parameters at runtime. If set to "yes", a dialog is constructed from definitions in an XML file. If set to any other value, no dialog is provided.<br />
*<b><tt><font size=4>dialogName</font></tt></b>: The name of an XML file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. If the file is not found on the server, CTPClient looks for the file in the same directory in which the program is running. If that fails, CTPClient looks for the default dialog file built into the application (<b><tt>DIALOG.xml</tt></b>). If the XML file cannot be found, the dialog is disabled, even if the dialogEnabled parameter is set to "yes". Values provided by the user in the dialog are treated as if they were options included in the start command of the program. {See [[#The Dialog XML Schema|The Dialog XML Schema]] for a description of how to configure the dialog.) <br />
*<b><tt><font size=4>showDialogButton</font></tt></b>: Specifies whether to display a button allowing the user to display the dialog. If set to "no", a dialog button is not displayed. If set to any other value, the dialog button is displayed.<br />
<br />
====Processing Pipeline Parameters====<br />
*<b><tt><font size=4>dfEnabled</font></tt></b>: Specifies whether to use the DicomFilter to select objects for processing. If set to "yes", objects are selected using the DicomFilter script. If set to any other value, no filtering is done.<br />
*<b><tt><font size=4>dfScriptName</font></tt></b>: The name of a DicomFilter script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient looks for the default script (<b><tt>DF.script</tt></b>) built into the application. If no default script is found, the DicomFilter stage is disabled, even if the dfEnabled parameter is set to "yes".<br />
*<b><tt><font size=4>dpaEnabled</font></tt></b>: Specifies whether the DicomPixelAnonymizer is to be included in the processing of objects. If set to "yes", objects are processed using the DicomPixelAnonymizer script. If set to any other value, no pixel anonymization is done.<br />
*<b><tt><font size=4>dpaScriptName</font></tt></b>: The name of a DicomPixelAnonymizer script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient looks for the default script (<b><tt>DPA.script</tt></b>) built into the application. If no default script is found, the DicomPixelAnonymizer stage is disabled, even if the dpaEnabled parameter is set to "yes".<br />
*<b><tt><font size=4>setBurnedInAnnotation</font></tt></b>: Specifies whether the BurnedInAnnotation element is to be set to "NO" for DICOM objects that match a DicomPixelAnonymizer signature. If set to "yes", the element value is set, if the parameter is missing or has any other value, the element is not modified. <br />
*<b><tt><font size=4>daScriptName</font></tt></b>: The name of a DicomAnonymizer script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient uses the default script (<b><tt>DA.script</tt></b>) built into the application.<br />
*<b><tt><font size=4>daLUTName</font></tt></b>: The name of a DicomAnonymizer lookup table file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the lookup table file from the server. When not present, CTPClient looks for the default lookup table (<b><tt>LUT.properties</tt></b>) built into the application. If no lookup table is available, an empty lookup table is provided.<br />
<br />
In addition to the standard parameters above, CTPClient supports special parameters for modifying the DicomAnonymizer script parameters and lookup table entries. <br />
<br />
Any parameter name starting with the at-sign ( '@' ) is treated as an anonymizer script modification. The '@' is removed, and the rest of the parameter name is used as the name of a script PARAM. The parameter value (the text after the '=' character) is used as the value for that PARAM. The intent of this feature is to allow a standard script to be tailored for a specific image acquisition site. Note that this feature does not allow element scripts to be modified; it only allows script PARAM values to be changed.<br />
<br />
Any parameter name starting with the dollar-sign ( '$' ) is treated as a lookup table modification. The '$' is removed, and the rest of the parameter name is used as the lookup table key. The parameter value (the text after the '=' character) is used as the value for that key. The intent of this feature is to allow a standard lookup table to be tailored for a specific image acquisition site.<br />
<br />
For more information on anonymizer parameters and lookup tables, see [[The CTP DICOM Anonymizer]], [[The CTP DICOM Anonymizer Configurator]], and [[The CTP Lookup Table Editor]].<br />
<br />
====Export Service Parameters====<br />
*<b><tt><font size=4>httpURL</font></tt></b>: The URL of the destination HttpImportService. If this parameter is not supplied, or if it is blank, the HttpExportService is disabled. This parameter must be a complete URL, including the protocol (http://IP:port or https://IP:port).<br />
*<b><tt><font size=4>showURL</font></tt></b>: "yes" to display a UI field for entering the URL of the destination HttpImportService. "no" to suppress the UI field, thus forcing the URL to be the value of the <b><tt>httpURL</tt></b> parameter. The default value is "yes".<br />
*<b><tt><font size=4>zip</font></tt></b>: "yes" to zip files before transmission via HTTP. The default value is "no". This feature is intended only for transmissions to a CTP site with an HttpImportService configured with a zip parameter set to "yes".<br />
*<b><tt><font size=4>xnatAuthURL</font></tt></b>: The URL of the XNAT server's authentication service. If this parameter is not supplied, or if it is blank, no authentication is performed, and the XNAT session cookie is not supplied in transfers. This parameter must be a complete URL, including the protocol (e.g. http://IP:port/data/JSESSION).<br />
*<b><tt><font size=4>xnatUsername</font></tt></b>: The username for authentication on the XNAT server.<br />
*<b><tt><font size=4>xnatPassword</font></tt></b>: The password for authentication on the XNAT server.<br />
*<b><tt><font size=4>xnatCookiename</font></tt></b>: The session cookie name used by the XNAT server. If this parameter is missing, the default name "JSESSION" is supplied.<br />
*<b><tt><font size=4>dicomURL</font></tt></b>: The URL of the destination DICOM Storage SCP (e.g. PACS or workstation). If this parameter is not supplied, or if it is blank, the DicomExportService is disabled. This parameter must be a complete URL, including the protocol (e.g. dicom://CalledAET:CallingAET@IP:port).<br />
*<b><tt><font size=4>stowURL</font></tt></b>: The URL of the destination DICOM STOW-RS Service. If this parameter is not supplied, or if it is blank, the DicomSTOWRSExportService is disabled. This parameter must be a complete URL, including the protocol (e.g. http://ip:port).<br />
*<b><tt><font size=4>stowUsername</font></tt></b>: The username to be used when authenticating with the destination DICOM STOW-RS Service. If this parameter is not supplied, or if it is blank, authentication credentials are not supplied when transferring to the destination system.<br />
*<b><tt><font size=4>stowPassword</font></tt></b>: The password to be used when authenticating with the destination DICOM STOW-RS Service.<br />
*<b><tt><font size=4>exportDirectory</font></tt></b>: The path to a directory in which processed files are to be stored. Files are stored with names constructed from their SOPInstanceUIDs. If this parameter is not supplied, or if it is blank, the DirectoryStorageService is disabled.<br />
*<b><tt><font size=4>renameFiles</font></tt></b>: Whether to rename exported files in the form Study_Series_Acquisition_Instance.dcm. If this parameter is not supplied, or if its value is not "yes", files are named by their SOPInstanceUID values.<br />
<br />
Note: If CTPClient is configured to export to an HTTP destination that requires authentication, the credentials can be included in the httpURL parameter like this: http://username:password@IPAddress:port. If the credentials are omitted from the URL and the destination requires them, CTPClient displays a dialog allowing the user to enter the credentials at the time of transmission.<br />
<br />
====Webstart Parameters====<br />
The Application Server supplies three parameters automatically when starting CTPClient. These are used by CTPClient to contact the server when the <b><tt>dfScriptName</tt></b>, <b><tt>dpaScriptName</tt></b>, <b><tt>daScriptName</tt></b>, or <b><tt>daLUTName</tt></b> parameters are supplied. If CTPClient is not started via webstart and the project requires that files be obtained from a server, the three parameters below must be supplied explicitly.<br />
<br />
*<b><tt><font size=4>protocol</font></tt></b>: The protocol to be used for communication with the CTP site's web server.<br />
*<b><tt><font size=4>host</font></tt></b>: The host IP address or domain name (and port) of the CTP site's web server.<br />
*<b><tt><font size=4>application</font></tt></b>: The name of the application ("<b><tt>CTPClient</tt></b>").<br />
<br />
====Debugging Parameters====<br />
When processing very large (typically multi-frame) objects, it may be necessary to allocate more than the default memory to the application using the <b><tt>max-heap-size</tt></b> attribute described in [[Using the CTP Application Server]]. To make it easy to see how much memory is in use, a button can be displayed in the application's window footer bar by enabling the <b><tt>showMemory</tt></b> parameter.<br />
*<b><tt><font size=4>showMemory</font></tt></b>: "yes" to display the button. The default is "no".<br />
<br />
===Default Configuration===<br />
====Webstart====<br />
For CTPClient instances that are run via Java webstart, it is possible to predefine parameter values in the <tt><b>CTPClient.xsl</b></tt> file stored on the server. This file will be located under the <tt><b>CTP/ROOT</b></tt> directory, typically in a first-generation child called CTPClient, although it is possible to locate it at a lower level, as in <tt><b>CTP/ROOT/MyTrial/CTPClient</b></tt>. The standard <tt><b>CTPClient.xsl</b></tt> file looks like this:<br />
<br />
<pre><br />
<?xml version="1.0" encoding="iso-8859-1"?><br />
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><br />
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" /><br />
<br />
<xsl:template match="/jnlp"><br />
<jnlp<br />
codebase="{environment/protocol}://{environment/host}/{environment/application}" ><br />
<!-- href="{environment/application}.jnlp" > --><br />
<br />
<information><br />
<title>CTP Client Utility</title><br />
<vendor>RSNA</vendor><br />
<homepage href="http://mircwiki.rsna.org/index.php?title=CTP-The_RSNA_Clinical_Trial_Processor"/><br />
<description>CTP Client Utility</description><br />
<description kind="short">Java Web Start program for transmitting data to CTP for clinical trials.</description><br />
<!-- <offline-allowed/> --><br />
</information><br />
<br />
<security><br />
<all-permissions/><br />
</security><br />
<br />
<resources><br />
<j2se version="1.6+"/><br />
<jar href="CTPClient.jar"/><br />
<jar href="CTP.jar"/><br />
<jar href="dcm4che.jar"/><br />
<jar href="dcm4che-imageio-rle-2.0.25.jar"/><br />
<jar href="jdbm.jar"/><br />
<jar href="log4j.jar"/><br />
<jar href="util.jar"/><br />
</resources><br />
<br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</jnlp><br />
</xsl:template><br />
<br />
<xsl:template match="param"><br />
<argument>"<xsl:value-of select="."/>"</argument><br />
</xsl:template><br />
<br />
</xsl:stylesheet><br />
</pre><br />
<br />
To predefine parameters, add <tt><b>argument</b></tt> elements to the <tt><b>application-desc</b></tt> element like this:<br />
<br />
<pre><br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<argument>"name1=value1"</argument><br />
<argument>"name2=value2"</argument><br />
<argument>"name3=value3"</argument><br />
...etc...<br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</pre><br />
<br />
For example:<br />
<br />
<pre><br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<argument>"panelTitle=My Trial CTP Client"</argument><br />
<argument>"showBrowseButton=yes"</argument><br />
<argument>"dialogName=DIALOG.xml"</argument><br />
<argument>"httpURL=http://theURL:80"</argument><br />
<argument>"showURL=yes"</argument><br />
<argument>"daScriptName=CTPClient.script"</argument><br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</pre><br />
<br />
Note that by placing the predefined parameters before the <tt><b>xsl:apply-templates</b></tt> instruction, any parameters that are included in the URL itself will override the defaults.<br />
<br />
====Local====<br />
For CTPClient instances that are installed locally, it is possible to predefine parameter values in a properties file. The file must be called <tt><b>config.default</b></tt>, and it must be stored in the same directory as CTPClient.jar. Here is an example:<br />
<br />
<pre><br />
windowTitle=My Trial<br />
PanelTitle=My Trial<br />
helpURL=http://ctp.myUniversity.edu/myTrial/help.html<br />
dialogEnabled=yes<br />
dialogName=myTrialDialog.xml<br />
showDialogButton=no<br />
dfEnabled=no<br />
dpaEnabled=yes<br />
daScriptName=myTrialDAScript.script<br />
httpURL=http://ctp.PrincipalInvestigator.org:9999<br />
showURL=no<br />
showBrowseButton=yes<br />
</pre><br />
<br />
Properties files use the backslash character for escaping special characters, so if a backslash character is required in a property, it must be escaped by a backslash. Even on a Windows system, forward slashes work in specifying file paths in property values.<br />
<br />
==The Dialog XML Schema==<br />
When the <b><tt>dialogEnabled</tt></b> parameter is set to "yes", CTPClient loads an XML file to define the contents of a dialog allowing the user to enter values for parameters. The following is an example XML structure specifying three parameters:<br />
<br />
<pre><br />
<dialog title="New Patient" mode="study"><br />
<h>Site Parameters</h><br />
<p><br />
Enter the ID value for this site.<br />
</p><br />
<param<br />
name="@SITEID"<br />
label="Site ID"<br />
value=""/><br />
<h>Patient Parameters</h><br />
<p><br />
Enter the ID and name values for this patient.<br />
</p><br />
<param<br />
name="@SUBJECTID"<br />
label="Subject ID"<br />
value=""/><br />
<param<br />
name="@SUBJECTNAME"<br />
label="Subject Name"<br />
value=""/><br />
</dialog><br />
</pre><br />
<br />
The <b><tt>title</tt></b> attribute of the root element specifies the title of the popup. The title is also used as the name of the button in the main CTPClient window for displaying the dialog, so it should be fairly short.<br />
<br />
The <b><tt>mode</tt></b> attribute of the root element specifies the whether the dialog is to be displayed once for each study transmitted ("study" mode) or once for each click of the Start button ("session" mode). The default is study mode.<br />
<br />
The <b><tt>h</tt></b> element specifies a heading. The element has one optional attribute, <b><tt>align</tt></b>, with allowed values <b><tt>left</tt></b>, <b><tt>center</tt></b>, and <b><tt>right</tt></b>, The default is <b><tt>center</tt></b>.<br />
<br />
The <b><tt>p</tt></b> element specifies a paragraph. Word wrapping is not provided; lines are broken at newline characters. The element has one optional attribute, <b><tt>align</tt></b>, with allowed values <b><tt>left</tt></b>, <b><tt>center</tt></b>, and <b><tt>right</tt></b>, The default is <b><tt>left</tt></b>.<br />
<br />
The <b><tt>param</tt></b> element specifies a parameter whose value is to be entered into the dialog by the user. <br />
* The <b><tt>name</tt></b> attribute specifies the name of an option parameter.<br />
* The <b><tt>label</tt></b> attribute specifies the text to be displayed beside the entry field for the parameter.<br />
* The <b><tt>value</tt></b> attribute specifies the initial value provided in the entry field. If a value was provided by an option parameter when CTPClient was started, that value takes precedence over the value of the <b><tt>value</tt></b> attribute.<br />
<br />
Parameter names starting with <b><tt>@</tt></b> specify PARAM values in DicomAnonymizer scripts.<br />
<br />
Parameter names starting with <b><tt>$</tt></b> specify values in DicomAnonymizer lookup tables.<br />
<br />
The <b><tt>param</tt></b> element has an optional <b><tt>readonly</tt></b> attribute. When set to <b><tt>yes</tt></b>, the entry in the table is not editable. <br />
*If the <b><tt>name</tt></b> attribute is specified and the <b><tt>value</tt></b> attribute is missing or blank, the text displayed is the value of the specified configuration parameter.<br />
*If the <b><tt>value</tt></b> attribute is not blank, it takes precedence over any configuration parameter specified by the <b><tt>name</tt></b> attribute.<br />
*Examples:<br />
<pre><br />
<param<br />
name="@SITEID"<br />
label="Site ID:"<br />
readonly="yes"/><br />
<param<br />
label="Note:"<br />
value="Some readonly text"<br />
readonly="yes"/><br />
</pre><br />
<br />
==Building CTPClient==<br />
In some trials, it may be desired to build a special version of CTPClient with pre-configured values in the configuration files.<br />
<br />
The source code for CTPClient is on GitHub at https://github.com/johnperry/CTPClient.<br />
<br />
The default configuration files are located in the <b><tt>source/files</tt></b> directory:<br />
* <b><tt>config.properties</tt></b><br />
* <b><tt>DPA.script</tt></b><br />
* <b><tt>DA.script</tt></b><br />
<br />
In special situations, default files for the dialog, DicomFilter and DicomAnonymizer lookup table can be provided. The following are the names required by the application:<br />
<br />
* <b><tt>DIALOG.xml</tt></b><br />
* <b><tt>DF.script</tt></b><br />
* <b><tt>LUT.properties</tt></b><br />
<br />
The program is built using <b><tt>ant</tt></b>. After the build is complete, a zip file containing all the files necessary for deployment is located in the <b><tt>products</tt></b> directory.<br />
<br />
==Deploying CTPClient on the CTP Application Server==<br />
As described in [[Using the CTP Application Server]], all the files for CTPClient must be placed in the <b><tt>CTP/ROOT/CTPClient</tt></b> directory. The latest version is encapsulated in a zip file on the RSNA MIRC site at http://mirc.rsna.org/download/CTPClient.zip. <br />
<br />
Included in the zip file is the XSL file required by the Application Server for automatic creation of the webstart <b><tt>jnlp</tt></b> file.<br />
<br />
To deploy CTPClient, create the CTP/ROOT/CTPClient directory and copy all the files from the zip file into it.<br />
<br />
Note: If multiple CTPClient instances are to be supported in one CTP instance, install them in subdirectories of the ROOT directory, like this:<br />
<br />
:ROOT<br />
::TrialX<br />
:::CTPClient<br />
::TrialY<br />
:::CTPClient<br />
::TrialZ<br />
:::CTPClient<br />
<br />
In this situation, the URL to access a trial's CTPClient would include the trial name in the webstart path (e.g. /webstart/TrialY/CTPClient[?params]).</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=Configuring_the_CTPClient_Application_for_Clinical_Trials&diff=8037Configuring the CTPClient Application for Clinical Trials2018-06-30T18:04:40Z<p>Johnperry: /* ExportServices */</p>
<hr />
<div>The CTPClient application is a program for anonymizing images and transmitting them from image acquisition sites to principal investigator sites in clinical trials. This article describes how to configure, distribute, and run the program. The intended audience for this article is clinical trial administrators and their software minions.<br />
<br />
==Running CTPClient==<br />
CTPClient can be launched via the Java webstart mechanism, thus removing the necessity for installing CTP applications at the image acquisition sites. When run via webstart, the user accesses a URL on the principal investigator's CTP site, and the browser downloads CTPClient and starts it. The recommended method for launching CTPClient via webstart is to use the CTP Application Server on the CTP site. For general information on the Application Server, see [[Using the CTP Application Server]].<br />
<br />
CTPClient can also be launched as a stand-alone application installed on the client computer. When run stand-alone, the program is started by double-clicking the program's icon or by launching a command window and entering the command:<br />
<br />
:<b><tt>java -jar CTPClient.jar [options]</tt></b><br />
<br />
where [options] is a series of quoted parameters, each in the form:<br />
<br />
:<b><tt>"param=value"</tt></b><br />
<br />
==The Processing Pipeline==<br />
===Import Services===<br />
CTPClient has two import mechanisms.<br />
* Locally stored files can be manually selected.<br />
* A DICOM Storage SCP can be enabled to receive files from PACS systems or workstations.<br />
<br />
===Processing Stages===<br />
CTPClient has a fixed processing pipeline consisting of these stages, in this order:<br />
* DicomFilter<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomAnonymizer<br />
<br />
The DicomFilter and DicomPixelAnonymizer stages must be explicitly enabled using the parameters described in the next section. The DicomDecompressor stage is run <u>only if</u> the object being processed matches a signature of the DicomPixelAnonymizer; otherwise, the object is not decompressed. See [[The CTP DICOM Pixel Anonymizer]] for more information.<br />
<br />
The DicomAnonymizer is always enabled.<br />
<br />
No default script is provided for the DicomFilter.<br />
<br />
Default scripts are provided for the DicomPixelAnonymizer and the DicomAnonymizer. <br />
<br />
No default lookup table is provided for the DicomAnonymizer.<br />
<br />
===ExportServices===<br />
CTPClient has four export services:<br />
* HttpExportService<br />
* DicomExportService<br />
* STOWRSExportService<br />
* DirectoryStorageService<br />
<br />
==Run-time Configuration==<br />
CTPClient is designed to be configured by setting the [options] parameters for the transmitting site. When run via webstart, these parameters can be supplied by query parameters in the URL, as in this example:<br />
<br />
:<b><tt>http://ctp.university.edu/webstart/CTPClient?param1=value1&param2=value2</tt></b><br />
<br />
Note that when a value includes whitespace or any other characters that are illegal in a URL, the value must be URL-encoded.<br />
<br />
As mentioned in [[#Building CTPClient|Building CTPClient]], below, a special CTPClient build can be created for specific applications, including application-specific files and configuration parameters.<br />
<br />
===Configuration Parameters===<br />
The parameters supported by the program are shown below.<br />
<br />
====Window Display Parameters====<br />
*<b><tt><font size=4>windowTitle</font></tt></b>: The text to be shown in the title bar of the CTP Client window. The default is "CTP Client".<br />
*<b><tt><font size=4>panelTitle</font></tt></b>: The text to be shown at the top of the main pane in the CTPClient UI. The default is "CTP Client".<br />
*<b><tt><font size=4>helpURL</font></tt></b>: The URL to be accessed when the user clicks the Help button on the CTPClient UI. If this parameter is missing, the Help button is not displayed.<br />
<br />
====Import Service Parameters====<br />
*<b><tt><font size=4>showBrowseButton</font></tt></b>: Specifies whether to display a button allowing the user to browse the local disk for images to display. If an scpPort is defined and the showBrowseButton parameter is set to "no", a browse button is not displayed. If the parameter is set to any other value, the dialog button is displayed, whether an scpPort parameter is supplied or not. <br />
*<b><tt><font size=4>scpPort</font></tt></b>: The port on which CTPClient is to start a DICOM Storage SCP to receive objects via the DICOM protocol. If set to any integer greater than zero, CTPClient starts the SCP and accepts transfers from DICOM Storage SCUs. If the parameter is not supplied, or if it is blank or a non-integer value, the SCP is disabled. The default configuration does not enable the SCP.<br />
*<b><tt><font size=4>acceptNonImageObjects</font></tt></b>: Specifies whether non-image objects are to be selected for processing. If set to "yes", all objects are accepted. If set to any other value, only images are accepted. The default configuration only accepts image objects.<br />
*<b><tt><font size=4>dialogEnabled</font></tt></b>: Specifies whether to provide a dialog for entry of parameters at runtime. If set to "yes", a dialog is constructed from definitions in an XML file. If set to any other value, no dialog is provided.<br />
*<b><tt><font size=4>dialogName</font></tt></b>: The name of an XML file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. If the file is not found on the server, CTPClient looks for the file in the same directory in which the program is running. If that fails, CTPClient looks for the default dialog file built into the application (<b><tt>DIALOG.xml</tt></b>). If the XML file cannot be found, the dialog is disabled, even if the dialogEnabled parameter is set to "yes". Values provided by the user in the dialog are treated as if they were options included in the start command of the program. {See [[#The Dialog XML Schema|The Dialog XML Schema]] for a description of how to configure the dialog.) <br />
*<b><tt><font size=4>showDialogButton</font></tt></b>: Specifies whether to display a button allowing the user to display the dialog. If set to "no", a dialog button is not displayed. If set to any other value, the dialog button is displayed.<br />
<br />
====Processing Pipeline Parameters====<br />
*<b><tt><font size=4>dfEnabled</font></tt></b>: Specifies whether to use the DicomFilter to select objects for processing. If set to "yes", objects are selected using the DicomFilter script. If set to any other value, no filtering is done.<br />
*<b><tt><font size=4>dfScriptName</font></tt></b>: The name of a DicomFilter script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient looks for the default script (<b><tt>DF.script</tt></b>) built into the application. If no default script is found, the DicomFilter stage is disabled, even if the dfEnabled parameter is set to "yes".<br />
*<b><tt><font size=4>dpaEnabled</font></tt></b>: Specifies whether the DicomPixelAnonymizer is to be included in the processing of objects. If set to "yes", objects are processed using the DicomPixelAnonymizer script. If set to any other value, no pixel anonymization is done.<br />
*<b><tt><font size=4>dpaScriptName</font></tt></b>: The name of a DicomPixelAnonymizer script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient looks for the default script (<b><tt>DPA.script</tt></b>) built into the application. If no default script is found, the DicomPixelAnonymizer stage is disabled, even if the dpaEnabled parameter is set to "yes".<br />
*<b><tt><font size=4>setBurnedInAnnotation</font></tt></b>: Specifies whether the BurnedInAnnotation element is to be set to "NO" for DICOM objects that match a DicomPixelAnonymizer signature. If set to "yes", the element value is set, if the parameter is missing or has any other value, the element is not modified. <br />
*<b><tt><font size=4>daScriptName</font></tt></b>: The name of a DicomAnonymizer script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient uses the default script (<b><tt>DA.script</tt></b>) built into the application.<br />
*<b><tt><font size=4>daLUTName</font></tt></b>: The name of a DicomAnonymizer lookup table file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the lookup table file from the server. When not present, CTPClient looks for the default lookup table (<b><tt>LUT.properties</tt></b>) built into the application. If no lookup table is available, an empty lookup table is provided.<br />
<br />
In addition to the standard parameters above, CTPClient supports special parameters for modifying the DicomAnonymizer script parameters and lookup table entries. <br />
<br />
Any parameter name starting with the at-sign ( '@' ) is treated as an anonymizer script modification. The '@' is removed, and the rest of the parameter name is used as the name of a script PARAM. The parameter value (the text after the '=' character) is used as the value for that PARAM. The intent of this feature is to allow a standard script to be tailored for a specific image acquisition site. Note that this feature does not allow element scripts to be modified; it only allows script PARAM values to be changed.<br />
<br />
Any parameter name starting with the dollar-sign ( '$' ) is treated as a lookup table modification. The '$' is removed, and the rest of the parameter name is used as the lookup table key. The parameter value (the text after the '=' character) is used as the value for that key. The intent of this feature is to allow a standard lookup table to be tailored for a specific image acquisition site.<br />
<br />
For more information on anonymizer parameters and lookup tables, see [[The CTP DICOM Anonymizer]], [[The CTP DICOM Anonymizer Configurator]], and [[The CTP Lookup Table Editor]].<br />
<br />
====Export Service Parameters====<br />
*<b><tt><font size=4>httpURL</font></tt></b>: The URL of the destination HttpImportService. If this parameter is not supplied, or if it is blank, the HttpExportService is disabled. This parameter must be a complete URL, including the protocol (http://IP:port or https://IP:port).<br />
*<b><tt><font size=4>showURL</font></tt></b>: "yes" to display a UI field for entering the URL of the destination HttpImportService. "no" to suppress the UI field, thus forcing the URL to be the value of the <b><tt>httpURL</tt></b> parameter. The default value is "yes".<br />
*<b><tt><font size=4>zip</font></tt></b>: "yes" to zip files before transmission via HTTP. The default value is "no". This feature is intended only for transmissions to a CTP site with an HttpImportService configured with a zip parameter set to "yes".<br />
*<b><tt><font size=4>dicomURL</font></tt></b>: The URL of the destination DICOM Storage SCP (e.g. PACS or workstation). If this parameter is not supplied, or if it is blank, the DicomExportService is disabled. This parameter must be a complete URL, including the protocol (e.g. dicom://CalledAET:CallingAET@IP:port).<br />
*<b><tt><font size=4>stowURL</font></tt></b>: The URL of the destination DICOM STOW-RS Service. If this parameter is not supplied, or if it is blank, the DicomSTOWRSExportService is disabled. This parameter must be a complete URL, including the protocol (e.g. http://ip:port).<br />
*<b><tt><font size=4>stowUsername</font></tt></b>: The username to be used when authenticating with the destination DICOM STOW-RS Service. If this parameter is not supplied, or if it is blank, authentication credentials are not supplied when transferring to the destination system.<br />
*<b><tt><font size=4>stowPassword</font></tt></b>: The password to be used when authenticating with the destination DICOM STOW-RS Service.<br />
*<b><tt><font size=4>exportDirectory</font></tt></b>: The path to a directory in which processed files are to be stored. Files are stored with names constructed from their SOPInstanceUIDs. If this parameter is not supplied, or if it is blank, the DirectoryStorageService is disabled.<br />
*<b><tt><font size=4>renameFiles</font></tt></b>: Whether to rename exported files in the form Study_Series_Acquisition_Instance.dcm. If this parameter is not supplied, or if its value is not "yes", files are named by their SOPInstanceUID values.<br />
<br />
Note: If CTPClient is configured to export to an HTTP destination that requires authentication, the credentials can be included in the httpURL parameter like this: http://username:password@IPAddress:port. If the credentials are omitted from the URL and the destination requires them, CTPClient displays a dialog allowing the user to enter the credentials at the time of transmission.<br />
<br />
====Webstart Parameters====<br />
The Application Server supplies three parameters automatically when starting CTPClient. These are used by CTPClient to contact the server when the <b><tt>dfScriptName</tt></b>, <b><tt>dpaScriptName</tt></b>, <b><tt>daScriptName</tt></b>, or <b><tt>daLUTName</tt></b> parameters are supplied. If CTPClient is not started via webstart and the project requires that files be obtained from a server, the three parameters below must be supplied explicitly.<br />
<br />
*<b><tt><font size=4>protocol</font></tt></b>: The protocol to be used for communication with the CTP site's web server.<br />
*<b><tt><font size=4>host</font></tt></b>: The host IP address or domain name (and port) of the CTP site's web server.<br />
*<b><tt><font size=4>application</font></tt></b>: The name of the application ("<b><tt>CTPClient</tt></b>").<br />
<br />
====Debugging Parameters====<br />
When processing very large (typically multi-frame) objects, it may be necessary to allocate more than the default memory to the application using the <b><tt>max-heap-size</tt></b> attribute described in [[Using the CTP Application Server]]. To make it easy to see how much memory is in use, a button can be displayed in the application's window footer bar by enabling the <b><tt>showMemory</tt></b> parameter.<br />
*<b><tt><font size=4>showMemory</font></tt></b>: "yes" to display the button. The default is "no".<br />
<br />
===Default Configuration===<br />
====Webstart====<br />
For CTPClient instances that are run via Java webstart, it is possible to predefine parameter values in the <tt><b>CTPClient.xsl</b></tt> file stored on the server. This file will be located under the <tt><b>CTP/ROOT</b></tt> directory, typically in a first-generation child called CTPClient, although it is possible to locate it at a lower level, as in <tt><b>CTP/ROOT/MyTrial/CTPClient</b></tt>. The standard <tt><b>CTPClient.xsl</b></tt> file looks like this:<br />
<br />
<pre><br />
<?xml version="1.0" encoding="iso-8859-1"?><br />
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><br />
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" /><br />
<br />
<xsl:template match="/jnlp"><br />
<jnlp<br />
codebase="{environment/protocol}://{environment/host}/{environment/application}" ><br />
<!-- href="{environment/application}.jnlp" > --><br />
<br />
<information><br />
<title>CTP Client Utility</title><br />
<vendor>RSNA</vendor><br />
<homepage href="http://mircwiki.rsna.org/index.php?title=CTP-The_RSNA_Clinical_Trial_Processor"/><br />
<description>CTP Client Utility</description><br />
<description kind="short">Java Web Start program for transmitting data to CTP for clinical trials.</description><br />
<!-- <offline-allowed/> --><br />
</information><br />
<br />
<security><br />
<all-permissions/><br />
</security><br />
<br />
<resources><br />
<j2se version="1.6+"/><br />
<jar href="CTPClient.jar"/><br />
<jar href="CTP.jar"/><br />
<jar href="dcm4che.jar"/><br />
<jar href="dcm4che-imageio-rle-2.0.25.jar"/><br />
<jar href="jdbm.jar"/><br />
<jar href="log4j.jar"/><br />
<jar href="util.jar"/><br />
</resources><br />
<br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</jnlp><br />
</xsl:template><br />
<br />
<xsl:template match="param"><br />
<argument>"<xsl:value-of select="."/>"</argument><br />
</xsl:template><br />
<br />
</xsl:stylesheet><br />
</pre><br />
<br />
To predefine parameters, add <tt><b>argument</b></tt> elements to the <tt><b>application-desc</b></tt> element like this:<br />
<br />
<pre><br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<argument>"name1=value1"</argument><br />
<argument>"name2=value2"</argument><br />
<argument>"name3=value3"</argument><br />
...etc...<br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</pre><br />
<br />
For example:<br />
<br />
<pre><br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<argument>"panelTitle=My Trial CTP Client"</argument><br />
<argument>"showBrowseButton=yes"</argument><br />
<argument>"dialogName=DIALOG.xml"</argument><br />
<argument>"httpURL=http://theURL:80"</argument><br />
<argument>"showURL=yes"</argument><br />
<argument>"daScriptName=CTPClient.script"</argument><br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</pre><br />
<br />
Note that by placing the predefined parameters before the <tt><b>xsl:apply-templates</b></tt> instruction, any parameters that are included in the URL itself will override the defaults.<br />
<br />
====Local====<br />
For CTPClient instances that are installed locally, it is possible to predefine parameter values in a properties file. The file must be called <tt><b>config.default</b></tt>, and it must be stored in the same directory as CTPClient.jar. Here is an example:<br />
<br />
<pre><br />
windowTitle=My Trial<br />
PanelTitle=My Trial<br />
helpURL=http://ctp.myUniversity.edu/myTrial/help.html<br />
dialogEnabled=yes<br />
dialogName=myTrialDialog.xml<br />
showDialogButton=no<br />
dfEnabled=no<br />
dpaEnabled=yes<br />
daScriptName=myTrialDAScript.script<br />
httpURL=http://ctp.PrincipalInvestigator.org:9999<br />
showURL=no<br />
showBrowseButton=yes<br />
</pre><br />
<br />
Properties files use the backslash character for escaping special characters, so if a backslash character is required in a property, it must be escaped by a backslash. Even on a Windows system, forward slashes work in specifying file paths in property values.<br />
<br />
==The Dialog XML Schema==<br />
When the <b><tt>dialogEnabled</tt></b> parameter is set to "yes", CTPClient loads an XML file to define the contents of a dialog allowing the user to enter values for parameters. The following is an example XML structure specifying three parameters:<br />
<br />
<pre><br />
<dialog title="New Patient" mode="study"><br />
<h>Site Parameters</h><br />
<p><br />
Enter the ID value for this site.<br />
</p><br />
<param<br />
name="@SITEID"<br />
label="Site ID"<br />
value=""/><br />
<h>Patient Parameters</h><br />
<p><br />
Enter the ID and name values for this patient.<br />
</p><br />
<param<br />
name="@SUBJECTID"<br />
label="Subject ID"<br />
value=""/><br />
<param<br />
name="@SUBJECTNAME"<br />
label="Subject Name"<br />
value=""/><br />
</dialog><br />
</pre><br />
<br />
The <b><tt>title</tt></b> attribute of the root element specifies the title of the popup. The title is also used as the name of the button in the main CTPClient window for displaying the dialog, so it should be fairly short.<br />
<br />
The <b><tt>mode</tt></b> attribute of the root element specifies the whether the dialog is to be displayed once for each study transmitted ("study" mode) or once for each click of the Start button ("session" mode). The default is study mode.<br />
<br />
The <b><tt>h</tt></b> element specifies a heading. The element has one optional attribute, <b><tt>align</tt></b>, with allowed values <b><tt>left</tt></b>, <b><tt>center</tt></b>, and <b><tt>right</tt></b>, The default is <b><tt>center</tt></b>.<br />
<br />
The <b><tt>p</tt></b> element specifies a paragraph. Word wrapping is not provided; lines are broken at newline characters. The element has one optional attribute, <b><tt>align</tt></b>, with allowed values <b><tt>left</tt></b>, <b><tt>center</tt></b>, and <b><tt>right</tt></b>, The default is <b><tt>left</tt></b>.<br />
<br />
The <b><tt>param</tt></b> element specifies a parameter whose value is to be entered into the dialog by the user. <br />
* The <b><tt>name</tt></b> attribute specifies the name of an option parameter.<br />
* The <b><tt>label</tt></b> attribute specifies the text to be displayed beside the entry field for the parameter.<br />
* The <b><tt>value</tt></b> attribute specifies the initial value provided in the entry field. If a value was provided by an option parameter when CTPClient was started, that value takes precedence over the value of the <b><tt>value</tt></b> attribute.<br />
<br />
Parameter names starting with <b><tt>@</tt></b> specify PARAM values in DicomAnonymizer scripts.<br />
<br />
Parameter names starting with <b><tt>$</tt></b> specify values in DicomAnonymizer lookup tables.<br />
<br />
The <b><tt>param</tt></b> element has an optional <b><tt>readonly</tt></b> attribute. When set to <b><tt>yes</tt></b>, the entry in the table is not editable. <br />
*If the <b><tt>name</tt></b> attribute is specified and the <b><tt>value</tt></b> attribute is missing or blank, the text displayed is the value of the specified configuration parameter.<br />
*If the <b><tt>value</tt></b> attribute is not blank, it takes precedence over any configuration parameter specified by the <b><tt>name</tt></b> attribute.<br />
*Examples:<br />
<pre><br />
<param<br />
name="@SITEID"<br />
label="Site ID:"<br />
readonly="yes"/><br />
<param<br />
label="Note:"<br />
value="Some readonly text"<br />
readonly="yes"/><br />
</pre><br />
<br />
==Building CTPClient==<br />
In some trials, it may be desired to build a special version of CTPClient with pre-configured values in the configuration files.<br />
<br />
The source code for CTPClient is on GitHub at https://github.com/johnperry/CTPClient.<br />
<br />
The default configuration files are located in the <b><tt>source/files</tt></b> directory:<br />
* <b><tt>config.properties</tt></b><br />
* <b><tt>DPA.script</tt></b><br />
* <b><tt>DA.script</tt></b><br />
<br />
In special situations, default files for the dialog, DicomFilter and DicomAnonymizer lookup table can be provided. The following are the names required by the application:<br />
<br />
* <b><tt>DIALOG.xml</tt></b><br />
* <b><tt>DF.script</tt></b><br />
* <b><tt>LUT.properties</tt></b><br />
<br />
The program is built using <b><tt>ant</tt></b>. After the build is complete, a zip file containing all the files necessary for deployment is located in the <b><tt>products</tt></b> directory.<br />
<br />
==Deploying CTPClient on the CTP Application Server==<br />
As described in [[Using the CTP Application Server]], all the files for CTPClient must be placed in the <b><tt>CTP/ROOT/CTPClient</tt></b> directory. The latest version is encapsulated in a zip file on the RSNA MIRC site at http://mirc.rsna.org/download/CTPClient.zip. <br />
<br />
Included in the zip file is the XSL file required by the Application Server for automatic creation of the webstart <b><tt>jnlp</tt></b> file.<br />
<br />
To deploy CTPClient, create the CTP/ROOT/CTPClient directory and copy all the files from the zip file into it.<br />
<br />
Note: If multiple CTPClient instances are to be supported in one CTP instance, install them in subdirectories of the ROOT directory, like this:<br />
<br />
:ROOT<br />
::TrialX<br />
:::CTPClient<br />
::TrialY<br />
:::CTPClient<br />
::TrialZ<br />
:::CTPClient<br />
<br />
In this situation, the URL to access a trial's CTPClient would include the trial name in the webstart path (e.g. /webstart/TrialY/CTPClient[?params]).</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8036MIRC CTP2018-01-26T13:59:32Z<p>Johnperry: /* EmailService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The subject, patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8035MIRC CTP2018-01-26T13:58:49Z<p>Johnperry: /* EmailService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
# The patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8034MIRC CTP2018-01-26T13:58:06Z<p>Johnperry: /* EmailService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
* The patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
# In the subject attribute, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows a subject that includes the StudyDescription element: <b><tt>Study (0008,1030)</tt></b>.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8033MIRC CTP2018-01-26T13:53:09Z<p>Johnperry: /* EmailService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial. If the subject text includes one or more DICOM tags, the values of the corresponding elements in the DICOM object are substituted in the subject text for the tags.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
* The patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=The_CTP_DICOM_Anonymizer&diff=8032The CTP DICOM Anonymizer2017-12-10T15:14:55Z<p>Johnperry: /* @dateinterval(DateElementName,KeyType,KeyElementName) */</p>
<hr />
<div>This article describes how to configure the DICOM anonymizer used in the ClinicalTrialProcessor (<b>CTP</b>) application. The intended audience for this information is clinical trial coordinators at principal investigator sites.<br />
<br />
<b>Important note: The CTP DICOM anonymizer is different from the anonymizer that is included in the Tomcat/MIRC site and FieldCenter applications. Specifically:<br />
* All the functions which use remapping tables have been replaced with ones that use hashing.<br />
* Some functions have been removed and replaced with others that are faster.<br />
</b><br />
<br />
For information about how to include the DICOM Anonymizer in a clinical trial pipeline, see [[CTP-The RSNA Clinical Trial Processor]].<br />
<br />
For information about how to use the CTP Pixel Anonymizer, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<br />
<br />
==Accessing the CTP Anonymizer Configurator==<br />
The ClinicalTrialProcessor application includes a webserver which is normally configured to listen on the standard port used by most servers (80). Accessing the server with a browser displays a home page containing buttons which link to servlets providing status and configuration information. The <b>DICOM Anonymizer Configurator</b> button displays a page listing all the anonymizers which are currently configured in the application, with their pipeline and stage names and a link pointing to the anonymizer script file. Clicking the link to a script file displays a page containing a table of all the DICOM elements, with <b>Select</b> checkboxes and <b>Replacement</b> text fields. At the bottom of the page is a button which saves any changes that have been made on the page.<br />
<br />
==Modifying DICOM Elements==<br />
The anonymizer has a simple scripting language. Each DICOM element can have its own replacement script containing contents and instructions for what to do with the element when it is processed.<br />
<br />
To cause the anonymizer to take direct action on an element when a DICOM object is received, place a check in the <b>Select</b> checkbox for the element. Elements that are unchecked are left intact unless they qualify for global action as described later.<br />
<br />
To replace the contents of an element with new static text, enter the text in the <b>Replacement</b> text field for the element. <br />
<br />
To remove an element from the DICOM object, use the <b>remove(&nbsp;)</b> function described below.<br />
<br />
To insert an empty element or replace the contents of an element with an empty (zero-length) string, use the <b>empty(&nbsp;)</b> function described below.<br />
<br />
Leading and trailing blanks in all Replacement fields are removed before processing.<br />
<br />
===Element Names===<br />
Some of the functions described below have arguments that specify the name of a DICOM element. Element names can be specified in several ways:<br />
*An element can be specified by using its DICOM keywork, or more precisely, the derivative of the keyword that is used by the DICOM library used by CTP (dcm4che). The dcm4che keywords are listed in the [http://mirc.rsna.org/dcm4che/api/org/dcm4che/dict/Tags.html tag dictionary] on the RSNA MIRC site. Element names are also shown on the DICOM Anonymizer Configurator page next to their numeric tags.<br />
<br />
*An element can also be specified by its numeric tag. Tags can be specified in the following forms:<br />
<tt><br />
:* ggggeeee<br />
:* (gggg,eeee)<br />
:* [ggggeeee]<br />
:* [gggg,eeee]<br />
</tt><br />
where <b>g</b> and <b>e</b> are hexadecimal values.<br />
<br />
* For elements in private groups, a special syntax is provided:<br />
<tt><br />
:* gggg[BlockID]ee<br />
:* gggg00[BlockID]<br />
</tt><br />
where <b>BlockID</b> is the value claimed in the Private Creator Data Element of the block. BlockID values are <b>not</b> case-sensitive. <br />
<br />
If a script defines a name for an element in a private group, that name can be used in scripts wherever an <b>ElementName</b> is required. For additional information, see [[The_CTP_DICOM_Anonymizer_Configurator#New_Element...|The CTP DICOM Anonymizer Configurator]].<br />
<br />
Wherever an <b>ElementName</b> is required, the keyword <b>this</b> may be used to indicate the element whose replacement value is being constructed.<br />
<br />
It is possible to reference elements in item datasets of sequence elements (elements with VR=SQ) by listing a series of element names separated by double-colons (::). Each element in the list except the last one must be an SQ element. An element's first item dataset is used to obtain the next element in the series. <br />
<br />
It is possible to reference an element in the root dataset by prefixing its specifier with "root:", e.g. root:PatientID or root:[0010,0010]. This may be of use when processing item datasets of sequence elements.<br />
<br />
This is an example that references an element in the first item dataset of element (0008,1140):<br />
*<tt>[0008,1140]::(0008,1150)</tt><br />
Note that both the square bracket and parenthesis notation is used in the example above. Both are equivalent. Note also that keywords could also have been used for either or both of the element names:<br />
*<tt>RefImageSeq::RefSOPClassUID</tt><br />
<br />
This is an example that references an element buried two levels down in a private group:<br />
*<tt>(0029[XYZ CT HEADER]40)::(0017[ALIGNMENT HEADER]42)</tt><br />
In the above example, group 29 exists in the root dataset of the object. In that group, element (0029,0011) contains the text, <tt>XYZ CT HEADER</tt>, thus reserving the block of elements from (0029,1100) through (0029,11FF). In that block, there is an SQ element (0029,1140). This is the element referenced by <tt>(0029[XYZ CT HEADER]40)</tt>. The first item dataset of that element contains private group 17, and in that group, there is an element (0017,0010) containing the text, <tt>ALIGNMENT HEADER</tt>, which reserves the block of elements from (0017,1000) through (0017,10FF). In that block, there is an element (0017,1042). This is the element referenced by <tt>(0017[ALIGNMENT HEADER]42)</tt>.<br />
<br />
===Functions===<br />
The anonymizer provides several functions that can be used to modify elements. Functions are invoked by a leading <b>@</b>, followed by the name of the function, followed by the arguments (if any) in parentheses. Function calls can be embedded in static text in the <b>Replacement</b> text field. Multiple function calls can appear in one element.<br />
<br />
To allow <b>@</b> characters to appear as static text, the anonymizer recognizes the <b>\</b> escape character, which forces the next character to be taken literally. To insert a <b>\</b> character, it is necessary to escape it, e.g. <b>\\</b>.<br />
<br />
When parsing function arguments, the anonymizer also recognizes the <b>\</b> escape character. The comma, parenthesis, and bracket characters must be escaped if they are part of an argument.<br />
<br />
====@always()====<br />
The <b>always</b> function forces the anonymizer to execute a script even if the target element is not present in the DicomObject, creating the target element if necessary. Unless this function is the first instruction in the script for an element, the script is not executed when the element is not present. The remainder of the script is executed like any other script, and it can contain function calls, text, parameter references, etc. For example, if it is desired to insert the current date in an element, creating the element if necessary, the function can be used as follows:<br />
:<tt>@always()@date()</tt><br />
<br />
====@append(){script}====<br />
The <b>append</b> function adds the value of a script to a multi-valued element. This function is provided to allow an anonymizer to update the DeIdentificationMethod element (0012,0063) with a string describing the anonymization that was done. The script contained in braces is executed like any other script, and it can contain function calls, text, parameter references, etc. For example, an anonymizer script which removes provenance information received from a remote site might use this script for the DeIdentificationMethod element:<br />
<br />
:<tt>@append(){CTP: provenance data removed: @date() - @time()}</tt><br />
<br />
The <b>append</b> can be used to append multiple values by separating the values by double-backslashes:<br />
<br />
:<tt>@append(){value1\\value2\\value3}</tt><br />
<br />
Note that the DICOM standard accords each value the full length allowed by the Value Representation of the element to which the values are being appended.<br />
<br />
====@call(id, args)====<br />
The <b>call</b> function provides access to anonymizer extensions contained in CTP plugins. The first argument must be the <B><tt>id</tt></b> attribute value of the referenced plugin. The remaining arguments are specified by the plugin. All the arguments are passed to the plugin.<br />
<br />
====@blank(n)====<br />
The <b>blank</b> function returns a string of blanks of length <b>n</b>. This function is provided to allow a fixed-length field to be blanked. The function call <b>@blank(0)</b> is equivalent to <b>@empty()</b>.<br />
<br />
====@contents(ElementName)====<br />
This <b>contents</b> function returns the contents of the DICOM element named by the argument.<br />
<br />
====@contents(ElementName,"regex")====<br />
This <b>contents</b> function returns the contents of the DICOM element named by the argument, after removing all the characters selected by the regular expression. If you are not familiar with regular expressions, get an experienced programmer to help you. The effect of the operation is the same as the Java statement: <br />
:<b>String.replaceAll("regex","");</b><br />
<br />
====@contents(ElementName,"regex","replacement")====<br />
This <b>contents</b> function returns the contents of the DICOM element named by the argument, after replacing all the characters selected by the regular expression with the characters contained in the replacement string. If you are not familiar with regular expressions, get an experienced programmer to help you. The effect of the operation is the same as the Java statement: <br />
:<b>String.replaceAll("regex","replacement");</b><br />
<br />
====@date(separator)====<br />
The <b>date</b> function returns the current date in the format <b>YYYY-MM-DD</b> where the “-“ character is replaced by the separator string. The value corresponds to the local date at the instant the anonymizer calls the function. To generate a DICOM-compliant date, use an empty separator string, e.g <b>@date()</b>.<br />
<br />
====@dateinterval(DateElementName,KeyType,KeyElementName)====<br />
The <b>dateinterval</b> function with three arguments returns the number of days between a date in an element specified by DateElementName and a date stored in the anonymizer's lookup table under the KeyType specified by the second argument and the key stored in the element specified by the value of KeyElementName. The KeyElement is always obtained from the root dataset, even when processing elements in the item datasets of SQ elements.<br />
<br />
The format of dates stored in the lookup table must be M/D/YYYY. See [[Using_the_DicomAnonymizer_dateinterval_Function]] for more information.<br />
<br />
====@dateinterval(DateElementName,KeyType,KeyElementName,origindate)====<br />
The <b>dateinterval</b> function with four arguments first computes the same interval as in the version with three arguments. It then adds the computed number of days to the date specified in the fourth argument and returns the resulting date. The date in the origindate argument must be in DICOM format (YYYYMMDD). The function returns dates in DICOM format.<br />
<br />
====@dateinterval(DateElementName,KeyType,KeyElementName,@ParameterName)====<br />
This version of the four-argument <b>dateinterval</b> function accepts the fourth argument (origindate) as a parameter reference.<br />
<br />
====@empty(&nbsp;)====<br />
The <b>empty</b> function returns a zero-length string. This function is provided to allow differentiation between a blank <b>Replacement</b> text field, which causes deletion of the element from the DICOM object, and an empty element.<br />
<br />
====@encrypt(ElementName,"key")====<br />
This <b>encrypt</b> function returns the contents of the DICOM element named by the argument, encrypting the value with the specified key. The key is a single-word string of any length.<br />
<br />
====@encrypt(ElementName,@ParameterName)====<br />
This <b>encrypt</b> function returns the contents of the DICOM element named by the argument, encrypting the value using the value of the specified parameter as the key.<br />
<br />
====@hash(ElementName)====<br />
The <b>hash</b> function computes the MD5 hash of an element's value and returns it as a base-10 digit string.<br />
<br />
====@hash(ElementName,maxCharsOutput)====<br />
This version of the <b>hash</b> function computes the MD5 hash of an element's value and returns it as a base-10 digit string of the specified maximum length.<br />
<br />
====@hashdate(ElementName,HashElementName)====<br />
The <b>hashdate</b> function adds a negative offset to a date. The offset is calculated by hashing the value of the element specified in the HashElementName argument, converting the hash value to an integer, computing that value modulus 3650, and negating it. The result is then used as the increment of the ElementName element in the incrementdate function.<br />
<br />
To increment dates differently for different patients while preserving the longitudinal relationships among that patient's studies, use this script:<br />
<br />
:::<b>@hashdate(this,PatientID)</b><br />
<br />
To increment dates differently for every study, use this script:<br />
<br />
:::<b>@hashdate(this,StudyInstanceUID)</b><br />
<br />
To increment dates differently for every object, use this script:<br />
<br />
:::<b>@hashdate(this,SOPInstanceUID)</b><br />
<br />
====@hashname(ElementName,maxCharsOutput)====<br />
The <b>hashname</b> function returns a numeric string of the specified length by computing the secure hash of the identified element's text. The algorithm is:<br />
#combine all the words into one string;<br />
#remove whitespace, apostrophes, and periods;<br />
#convert to uppercase;<br />
#compute the secure hash of the resulting string;<br />
#convert the binary result to a base-10 string;<br />
#return <b>maxCharsOutput</b> characters from the low-order end of the string.<br />
<br />
====@hashname(ElementName,maxCharsOutput,maxWordsInput)====<br />
This version of the <b>hashname</b> function operates like <b>@hashname(ElementName,maxCharsOutput)</b> except that it only accepts the first <b>maxWordsInput</b> words in the input element. This is the preferred method for producing hashed patient names because it can be used to suppress middle names, which may be absent, present as a full name, or present as an initial. In this case, a good approach would be <b>@hashname(PatientName,6,2)</b>.<br />
<br />
====@hashptid(siteID,ElementName)====<br />
The <b>hashptid</b> function is designed to re-identify patients, replacing their clinical PatientID field with a trial PatientID field that is generated from the old value. When the <b>hashptid</b> function is called, the anonymizer obtains the contents of the element identified by <b>ElementName</b> (typically PatientID), computes the MD5 hash of the value, and converts it to a base-10 digit string.<br />
<br />
The <b>hashptid</b> function recognizes a parameter reference for the siteID, and is typically coded as:<br />
:::<b>@hashptid(@SITEID,this)</b><br />
<br />
====@hashptid(siteID,ElementName,maxCharsOutput)====<br />
This version of the <b>hashptid</b> function operates like <b>@hashptid(siteID,ElementName)</b> except that it limits the length of the output string to the specified value.<br />
<br />
====@hashuid(root,ElementName)====<br />
The <b>hashuid</b> function is designed to create replacement UIDs from existing ones. The <b>root</b> argument is a text string containing the UID root for the institution (for example, <b>1.2.840.4267.32.</b>). The <b>hashuid</b> function creates a new UID by computing the MD5 hash of the existing UID, converting it to a base-10 digit string and prepending the root. If the <b>root</b> does not end in a period, the anonymizer appends a period.<br />
<br />
The <b>hashuid</b> function recognizes a parameter reference in the root argument, and is typically coded as:<br />
:::<b>@hashuid(@UIDROOT,this)</b><br />
<br />
====@hashuid(root,ElementName,ElementName2)====<br />
This is a specialized version of the <b>hashuid</b> function. Before computing the hash, it first obtains the <u>anonymized</u> value of ElementName2. It then appends that to the <u>un</u>anonymized value of ElementName and computes the hash. This version of the function is designed to allow a dataset to be used for multiple trials using a script for the SOPInstanceUID and StudyInstanceUID like:<br />
:::<b>@hashuid(@UIDROOT,this,PatientID)</b><br />
<br />
where the PatientID script involves an @lookup function call and the lookup table is changed for each trial.<br />
<br />
====@incrementdate(ElementName,incInDays)====<br />
The <b>incrementdate</b> function adds a constant offset to a date. The offset is specified in days in the <b>incInDays</b> argument. The offset can be positive or negative, with positive increments generating later dates. <br />
<br />
The <b>incrementdate</b> function recognizes a parameter reference in the incInDays argument, and is typically coded as: <br />
<br />
:::<b>@incrementdate(this,@DATEINC)</b><br />
<br />
====@initials(ElementName)====<br />
The <b>initials</b> function returns a string of uppercase characters constructed from the contents of the named element by taking the first letter of each field in the element and then placing the first character last in the string. The purpose of this function is to generate the patient’s initials from the contents of a <b>PatientName</b> element which is encoded as <b>Last^First^Middle</b>. In this example, the <b>@initials(PatientName)</b> function call would return <b>FML</b>.<br />
<br />
====@initials(ElementName, offset)====<br />
This <b>initials</b> function obtains the initials and then encrypts them using a Caesar cipher with the specified offset. A positive offset cycles in alphabetic order; a negative offset cycles in reverse alphabetic order. Characters are encrypted in three separate groups: upper case, lower case, and numeric. Offset characters remain in their groups. No other characters (punctuation, whitespace, etc.) are offset.<br />
<br />
====@integer(ElementName,KeyType,width)====<br />
The <b>integer</b> function returns a numeric string associated with the text of the named element. The purpose of this function is to generate a replacement string for an identifier. Replacement strings start at <b>1</b> and increment for each new value of the named element. The minimum width of the replacement string is specified by the <b>width</b> argument. If the numeric value required for a specific text is shorter than the width, the replacement string is padded with leading <b>0</b> characters. The <b>KeyType</b> argument provides separate streams of integers for different types of text. For example, the <b>@integer(this,ptid,3)</b> function call for the PatientID element would generate a sequence <b>001</b>, <b>002</b>, <b>003</b>, etc. as different values of the PatientID element were encountered. If there were a <b>@integer(this,ptname,3)</b> function call for the PatientName element in the same script, it would independently generate the same sequence as different patient names were encountered. If the <b>width</b> argument is missing or zero or negative, no padding of the resulting integer string is done.<br />
<br />
====@keep(&nbsp;)====<br />
The <b>keep</b> function forces the element to be preserved in the DICOM object. This function is provided to make it easy to preserve elements that would otherwise be removed by a global action. This function is equivalent to <b>@contents(this)</b>, but the <b>keep</b> function is preferred because it is less costly and it handles sequence elements that the <b>contents</b> function does not.<br />
<br />
====@lookup(ElementName,KeyType)====<br />
The <b>lookup</b> function maps values through a local lookup table. It is intended to be used for mapping values that are known to the local site. For instance, it can be used to map patient ID values to case numbers by preloading the lookup table with values matching each patient ID with the corresponding case number.<br />
<br />
To allow for mapping multiple types of values in one anonymization step, the <b>KeyType</b> argument identifies the category. Its value is any text string that does not contain a colon or equals sign. It is best to use a single descriptive word or abbreviation.<br />
<br />
The lookup table is a properties file. The format of the lookup table file is:<br />
<br />
:KeyType/value = replacement value<br />
<br />
For example, if you are remapping patient IDs to case numbers, you might have a lookup table file that looks like:<br />
<br />
:ptid/22 = 400<br><br />
:ptid/23 = 401<br><br />
:ptid/24 = 402<br><br />
:ptid/25 = 403<br><br />
:ptid/26 = 404<br><br />
:ptid/27 = 405<br><br />
<br />
If the <b>Replacement</b> field for the <b>PatientID</b> element is coded as <b>@lookup(this,ptid)</b> then a PatientID element with the value <b>25</b> will be mapped to the value <b>403</b>.<br />
<br />
If no value exists in the lookup table for an element, the anonymizer quarantines the object being anonymized.<br />
<br />
====@lookup(ElementName,KeyType,action)====<br />
This version of the <b>lookup</b> function provides the option to take other actions if the lookup table does not contain an entry for the value of the specified element. <br />
<br />
* If the the lookup attempt fails and the <b>action</b> argument has the value <b>remove</b>, the element being modified is removed from the anonymized object. <br />
* If the the lookup attempt fails and the <b>action</b> argument has the value <b>keep</b>, the element being modified is left unmodified in the anonymized object.<br />
* If the the lookup attempt fails and the <b>action</b> argument has the value <b>empty</b>, the element being modified is replaced with an empty string.<br />
* If the the lookup attempt fails and the <b>action</b> argument has the value <b>skip</b>, the anonymization of the entire object is aborted and the unmodified object is passed to the next stage.<br />
* If the lookup attempt fails and the <b>action</b> argument has the value <b>default</b> and there is a fourth argument, the element being modified is replaced by the fourth argument.<br />
* If the lookup attempt fails and the <b>action</b> argument has the value <b>ignore</b> and there is a fourth argument and the value of the first argument matches the regular expression specified by the fourth argument, the element being modified is replaced by the value of the first argument. The regular expression must be enclosed in double-quotes.<br />
* If the lookup attempt fails and the <b>action</b> argument has any other value, the object is quarantined.<br />
<br />
====@lowercase(ElementName)====<br />
This <b>lowercase</b> function returns the contents of the specified DICOM element, converted to lower case. If the element is missing or empty, it returns the empty string.<br />
<br />
====@modifydate(ElementName,year,month,day)====<br />
The <b>modifydate</b> function modifies the individual fields in a date. The <b>year</b>, <b>month</b>, and <b>day</b> parameters replace the corresponding values in the date. If a parameter is an asterisk, the corresponding value in the original date is preserved. The <b>modifydate</b> function recognizes parameter references in the arguments.<br />
<br />
For example, if the <b>StudyDate</b> element is coded as <b><tt>@modifydate(this,*,1,1)</tt></b>, the StudyDate will be reset to the first of January, leaving the year unmodified.<br />
<br />
====@param(@ParameterName)====<br />
The <b>param</b> function returns the contents of the named parameter. Parameters are stored in the script file and can be accessed by name, allowing their contents to be defined once and used many times in various elements. These parameter names are predefined:<br />
*TRIAL<br />
*SPONSOR<br />
*SITEID<br />
*SITENAME<br />
*PREFIX<br />
*SUFFIX<br />
*UIDROOT<br />
*DATEINC<br />
*KEY<br />
Other parameter names can be added manually using the DICOM Anonymizer Configurator.<br />
<br />
====@pathelement(ElementName,index)====<br />
The <b>pathelement</b> function returns the specified path element in a string of path elements separated by the '/' character. If index is zero or positive, it counts from the root of the path. Thus, 0 refers to the root element, 1 refers to the second, etc. If index is negative, it counts backward from the end of the path. Thus, –1 refers to the last path element, -2 refers to the penultimate, etc. If the indexed path element does not exist, the entire path is returned.<br />
<br />
====@process(&nbsp;)====<br />
The <b>process</b> function forces the anonymization of each of the item datasets in a sequence (SQ) element. This function is the equivalent of <tt>@keep()</tt> for all other element types.<br />
<br />
====@remove(&nbsp;)====<br />
The <b>remove</b> function forces the element to be removed from the DICOM object. It is equivalent to a blank Replacement field, but it is preferred because it is more visually apparent on the Anonymizer Configurator page.<br />
<br />
====@require(&nbsp;)====<br />
This <b>require</b> function creates an empty element if the current element does not exist in the object.<br />
<br />
====@require(ElementName)====<br />
This <b>require</b> function creates an element if the current element does not exist in the object. The current element’s contents are set to the contents of the named element. If the named element does not exist in the object, the created element is empty.<br />
<br />
====@require(ElementName,"default value")====<br />
This <b>require</b> function creates an element if the current element does not exist in the object. The current element’s contents are set to the contents of the named element. If the named element does not exist in the object, the created element’s contents are set to the default value.<br />
<br />
====@round(ElementName,groupsize)====<br />
The <b>round</b> function is intended for use on patient age elements to allow them to be binned into groups of <b>groupsize</b> size. The center of the first group is always at zero. Therefore, if the <b>PatientAge</b> element contains <b>57</b>, the function call <b>@round(PatientAge,10)</b> returns <b>60</b>.<br />
<br />
====@time(separator)====<br />
The <b>time</b> function returns the current 24-hour time in the format <b>HH:MM:SS</b> where the “:” character is replaced by the separator string. The time corresponds to the local time at the instant the anonymizer calls the function. To generate a DICOM-compliant date, use an empty separator string, e.g. <b>@time()</b>.<br />
<br />
====@truncate(ElementName,n)====<br />
The <b>truncate</b> function returns a substring of the contents of the DICOM element named by the argument. If <b>n</b> is positive, it returns the first <b>n</b> characters. If <b>n</b> is negative, it returns the last <b>n</b> characters. If <b>n</b> is larger than the length of the string, it returns the whole string. (Note that if <b>n</b> is zero, it returns an empty string.)<br />
<br />
====@uppercase(ElementName)====<br />
This <b>uppercase</b> function returns the contents of the specified DICOM element, converted to upper case. If the element is missing or empty, it returns the empty string.<br />
<br />
====@value(ElementName)====<br />
This <b>value</b> function returns the contents of the specified DICOM element. If the element is missing, the empty string is returned. This function is equvalent to <b>@contents(ElementName)</b>.<br />
<br />
====@value(ElementName,"default value")====<br />
This <b>value</b> function returns the contents of the specified DICOM element. If the element is missing or empty, it returns the specified default value.<br />
<br />
===Global Actions===<br />
The anonymizer supports global commands that either keep or remove entire groups or classes of groups. The format of these commands is described in the advanced sectioin below.<br />
<br />
====Keep group 18====<br />
Checking the "Keep group 18" box causes the anonymizer to preserve all group 18 elements. This selection overrides the "Remove unchecked elements" selection. Actions specified for checked group 18 elements take precedence over all global actions.<br />
<br />
====Keep group 20====<br />
Checking the "Keep group 20" box causes the anonymizer to preserve all group 20 elements. This selection overrides the “Remove unchecked elements” selection. Actions specified for checked group 20 elements take precedence over all global actions.<br />
<br />
====Keep group 28====<br />
Checking the "Keep group 28" box causes the anonymizer to preserve all group 28 elements. This selection overrides the “Remove unchecked elements” selection. Actions specified for checked group 28 elements take precedence over all global actions.<br />
<br />
====Keep safe private elements====<br />
Checking the "Keep safe private elements" box causes the anonymizer to preserve all private elements known not to contain PHI. It also preserves all Private Creator Elements. This selection overrides the “Remove private groups” selection. The index of safe private elements is maintained by Mallinckrodt Institute of Radiology on berhaslf of the National Cancer Institute. See [[The DICOM Anonymizer Keep Safe Private Elements Feature]].<br />
<br />
====Remove private groups====<br />
Checking the "Remove private groups" box causes the anonymizer to remove all elements in odd-numbered groups. These are private groups whose contents are not specified by the DICOM standard. Because these groups often contain PHI, they are usually removed when fully de-identifying a DICOM object. If the box is not checked, elements in private groups are kept.<br />
<br />
====Remove unchecked elements====<br />
Checking the "“Remove unchecked elements" box causes the anonymizer to remove all elements that have not been selected in the table for special handling. There are several exceptions to this action, however, where unselected elements are still preserved by default, even when removing unspecified elements:<br />
#The SOP Class UID<br />
#The SOP Instance UID<br />
#The Study Instance UID<br />
#Group 28 (the parameters describing the pixels)<br />
#Groups 60xx (overlays)<br />
To remove the first three elements requires specific action in their scripts. Generally, those elements are re-identified using the <b>hashuid</b> function or simply preserved without modification<br />
<br />
====Remove curves====<br />
Checking the "Remove curves" box causes the anonymizer to remove all elements in 50xx groups. These are groups which contain curve data.<br />
<br />
====Remove overlays====<br />
Checking the "Remove overlays" box causes the anonymizer to remove all elements in 60xx groups. These are overlays and are sometimes removed when fully de-identifying an object because they can contain PHI as annotations. The notation “not recommended” is simply to discourage an administrator from removing these groups unless he knows exactly what he is doing.<br />
<br />
===Conditional Functions===<br />
The anonymizer has a limited conditional capability designed to allow it to perform different actions depending on the content of an element. The form of the conditional statement is:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>@if(ElementName, condition, x) {true clause} {false clause}</b><br />
<br />
where the third argument, <b>x</b>, is used only if the condition requires it. The third argument can be a quoted string or a parameter reference (<b>@NAME</B>).<br />
<br />
Both clauses are required in the statement or the anonymizer will ignore any commands that appear in the replacement script after the true clause. Whitespace within the arguments or between the clauses is ignored.<br />
<br />
Multiple if statements are allowed in one <b>Replacement</b> field, but nested if statements are not supported. Function calls are allowed within the conditional clauses.<br />
<br />
====@if(ElementName,exists)====<br />
The exists conditional statement executes the true clause if the named element exists in the object, no matter what its value; otherwise, it executes the false clause.<br />
<br />
====@if(ElementName,isblank)====<br />
The isblank conditional statement executes the true clause if the named element is missing from the object or appears with a zero length or with a non-zero length and contains only blank characters; otherwise, it executes the false clause.<br />
<br />
====@if(ElementName,equals,"string")====<br />
The equals conditional statement executes the true clause if the value of the named element exactly equals the specified string; otherwise, it executes the false clause. The test is not case-sensitive.<br />
<br />
====@if(ElementName,contains,"string")====<br />
The contains conditional statement executes the true clause if the value of the named element contains the specified string; otherwise, it executes the false clause. The test is not case-sensitive.<br />
<br />
====@if(ElementName,matches,"regex")====<br />
The matches conditional statement executes the true clause if the contents of the named element match the regular expression; otherwise, it executes the false clause. If you are not familiar with regular expressions and you need to use this function, get an experienced programmer to help you. This function can be used to execute very complex tests on the contents of an element.<br />
====@if(ElementName,greaterthan,value)====<br />
The greaterthan conditional statement executes the true clause if the contents of the named element are numerically greater than the third argument; otherwise, it executes the false clause. Comparisons are done by filtering all non-numeric characters in both the element and the comparison value, converting the results to integers, and comparing the integers.<br />
<br />
====@quarantine(&nbsp;)====<br />
The <b>quarantine</b> function causes the anonymizer to abort the anonymization process and place the unmodified object in the quarantine for manual processing. The <b>quarantine</b> function must appear in a conditional clause of an <b>if</b> statement, but this is not enforced programmatically. If it were to appear in script that is executed during every anonymization, it would force the quarantining of every object.<br />
<br />
====@select(&nbsp;)====<br />
The <b>select</b> function is a conditional statement that provides two clauses. The first is executed if the dataset being processed is the top-level (root) dataset of the object. The second is executed if the dataset being processed is an item of a sequence element. The form of the select statement is:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>@select() {root clause} {item clause}</b><br />
<br />
Both clauses are required in the statement. Whitespace between the clauses is ignored. Conditional statements are not allowed in either clause. Function calls are allowed within the clauses.<br />
<br />
====@skip(&nbsp;)====<br />
The <b>skip</b> function causes the anonymizer to abort the anonymization process and to allow the unmodified object to continue through the system. It is intended to be used when it is possible to detect that an object has already been anonymized, thus preventing it from being anonymized a second time. The <b>skip</b> function must appear in a conditional clause of an <b>if</b> statement, but this is not enforced programatically. If it were to appear in a script that is executed during every anonymization, it would allow PHI through the process.<br />
<br />
===The DeIdentificationMethodCodeSeq Element===<br />
The <b>DeIdentificationMethodCodeSeq</b> element (0012,0064) is processed specially. If a script for the element is provided, it is always processed, even if the element is not present in the DicomObject. The <b>@always()</b> function is not allowed in the script for this element. <br />
<br />
The script for the element is required to be one or more de-identification codes as defined in the De-Identification Method table (CID 7050) of DICOM PS3.16. If multiple methods are to be recorded, their code values are separated by single slash characters ( / ). Whitespace in the script for this element is allowed for readability, but it is ignored during processing.<br />
<br />
When this script is processed, the <b>DeIdentificationMethodCodeSeq </b> element is created if necessary, and one item dataset is added to the element for each code in the script. Each item dataset includes the <b>CodingSchemeDesignator</b> (defined to be "DCM"), the <b>CodeValue</b>, and the <b>CodeMeaning</b>. The CodeMeaning is provided automatically from the table in the DICOM standard:<br />
<br />
::{| class="wikitable"<br />
|-<br />
| 113100<br />
| Basic Application Confidentiality Profile<br />
|-<br />
| 113101<br />
| Clean Pixel Data Option<br />
|-<br />
| 113102<br />
| Clean Recognizable Visual Features Option<br />
|-<br />
| 113103<br />
| Clean Graphics Option<br />
|-<br />
| 113104<br />
| Clean Structured Content Option<br />
|-<br />
| 113105<br />
| Clean Descriptors Option<br />
|-<br />
| 113106<br />
| Retain Longitudinal With Full Dates Option<br />
|-<br />
| 113107<br />
| Retain Longitudinal With Modified Dates Option<br />
|-<br />
| 113108<br />
| Retain Patient Characteristics Option<br />
|-<br />
| 113109<br />
| Retain Device Identity Option<br />
|-<br />
| 113110<br />
| Retain UIDs<br />
|-<br />
| 113111<br />
| Retain Safe Private Option<br />
|}<br />
<br />
For example, if an anonymization script file implements the <b>Basic Application Confidentiality Profile</b> and the <b>Retain Device Identity Option</b>, the script for this element should be:<br />
<br />
::<b><tt>113100 / 113109</tt></b><br />
<br />
There is a special code, <b><tt>RESET</tt></b>. When it appears as the first component of the script, all previous codes are removed from the element before processing the rest of the components in the script. In the example above, to remove all previous codes and then insert the two new codes, the script should be:<br />
<br />
::<b><tt>RESET / 113100 / 113109</tt></b><br />
<br />
===Examples===<br />
====Patient and Trial Identifiers====<br />
The best approach for a multi-center trial is to use the <b>hashptid</b> function:<br />
<br />
:<b>@hashptid(@SITEID,PatientID)</b><br />
<br />
This generates a fairly long identifier, however. An alternative is to use the <b>integer</b> function:<br />
<br />
:<b>@integer(PatientID,ptid,4)</b><br />
<br />
This can be combined with other text like this:<br />
<br />
:<b>C-@integer(PatientID,ptid,4)</b><br />
<br />
The result would be values like: <b>C-0001</b>, <b>C-0002</b>, <b>C-0003</b>, etc.<br />
<br />
Many other methods have been used for the automatic generation of replacements for IDs and names. For an ACCORD trial, the <b>PatientName</b> element must contain the case number followed by a delimiter character (“^”) and the field center identifier. If the case number is stored by the modality operator in the <b>PatientComments</b> element and the field center identifier is <b>CWR</b>, the <b>Replacement</b> text field for the <b>PatientName</b> element would read: <br />
<br />
:<b>@contents(PatientComments)^CWR</b><br />
<br />
For an ACCORD trial, the <b>OtherPatientIds</b> element must contain the word <b>ACCORD</b>. The <b>Replacement</b> field for the <b>OtherPatientIds</b> element would then read:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>ACCORD</b><br />
<br />
For the WHIMS trial, the <b>PatientName</b> element must contain the patient’s initials followed by a dash, the name of the trial, another dash, and the site’s identifier, which is configured in the <b>SITEID</b> parameter. The <b>Replacement</b> field for the <b>PatientName</b> element would then read: <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>@initials(PatientName)-WHIMS-@param(@SITEID)</b><br />
<br />
====UID Remapping====<br />
To generate new UIDs for the <b>StudyInstanceUID</b> using the UID root 1.2.840.123.321, the <b>Replacement</b> field for the <b>StudyInstanceUID</b> element would then read:<br />
<br />
:<b>@hashuid(1.2.840.123.321.,StudyInstanceUID)</b><br />
<br />
If one were remapping UIDs as in the function call above, it would be more efficient to define the <b>UIDROOT</b> parameter to have the value “1.2.840.123.321.” and code the calls as: <br />
<br />
:<b>@hashuid(@UIDROOT,StudyInstanceUID)</b><br />
<br />
If all UID replacements are generated in this way, it ensures that all UIDs are mapped to the same root. If the root does not end in a period, the anonymizer appends a period, but it is good form to supply it.<br />
<br />
====Keeping and Removing Elements====<br />
If the <b>Remove unspecified elements</b> box is checked and the value of an element must be preserved, the <b>Replacement</b> field for the element would then read: <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>@keep()</b><br />
<br />
If the <b>Keep group 18</b> box is checked, but a specific group 18 element must be removed, the <b>Replacement</b> field for that element would then read: <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>@remove()</b><br />
<br />
====Conditionally Modifying Elements====<br />
If the <b>InstitutionName</b> element is to be kept if it is present and non-blank, but replaced with static text if it is missing or blank, the <b>Replacement</b> field for the element would read:<br />
<br />
:<b><tt>@if(InstitutionName,isblank){My Hospital}{@keep()}</tt></b><br />
<br />
If the <b>StudyComments</b> element is being used to contain a trial patient ID and the ID must have exactly seven numeric digits, and if this element is to be copied to the <b>PatientID</b> element, the <b>Replacement</b> field for the <b>PatientID</b> element would read: <br />
<br />
:<b><tt>@contents(StudyComments)</tt></b><br />
<br />
And the <b>Replacement</b> field for the <b>StudyComments</b> element would read:<br />
<br />
:<b><tt>@if(StudyComments,matches,"\\d{7}.*"){@remove()}{@quarantine()}</tt></b><br />
<br />
Note that the coding of the regular expression in this case looks odd because the escape character is doubled. This is necessary because the anonymizer and the regular expression processor both use the same escape character, the backslash. Thus, to get one escape character, it must itself be escaped.<br />
<br />
Note also that the <b>true</b> clause will force the <b>StudyComments</b> element to be deleted from the object, which would be reasonable, since its contents are being moved to the <b>PatientID</b> field. If other processing were desired in this situation, it could be placed in the <b>true</b> clause.<br />
<br />
In this example, a better script for the <b>PatientID</b> element might be:<br />
<br />
:<b><tt>@contents(StudyComments,"\\D")</tt></b><br />
<br />
This will delete all non-numeric characters from the string used for the <b>PatientID</b>. Some modalities insert a newline character at the end of entry fields when the operator ends an entry with the Enter key. This script filters out those characters and anything else in the field that is not numeric. Note that the regular expression in the <b>StudyComments</b> script above ended with “.*”. That script will match a seven-digit string ending in a newline.<br />
<br />
====Conditionally Processing Files====<br />
The <b>skip</b> function can be used in the following way to avoid processing files that have already been processed. Suppose that the <b>ReferringPhysicianName</b> element is not used in the clinical trial. Its <b>Replacement</b> field could be coded as:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>@if(ReferringPhysicianName,matches,"DONE"){@skip()}{DONE}</b><br />
<br />
This will cause the anonymizer to insert the word <b>DONE</b> in the field on the first pass. If the object were to be processed again, the anonymizer would detect the word and skip the anonymization process.<br />
<br />
====Filtering Element Content====<br />
The <b>contents(ElementName,"regex")</b> function can be used to filter the contents of an element, selecting only a portion of its value. For example, suppose that the <b>StudyComments</b> element is populated by a modality with specially formatted content: a numeric code followed by other information including a user ID:<br />
<br />
:<b><tt>78.7812 [ADJUSTED: HE41328 - 01/02/2007 13:00:26]</tt></b><br />
<br />
The following function call would retrieve the leading code (<b>78.7812</b>):<br />
<br />
:<b><tt>@contents(StudyComments,"\\s.*")</tt></b><br />
<br />
The following function call would retrieve the user's ID (<b>HE41328</b>):<br />
<br />
:<b><tt>@contents(PatientName,"([^:]*:\\s+)|(\\s*-.*)")</tt></b><br />
<br />
====Processing SQ Elements====<br />
The anonymizer has three functions that apply to SQ elements:<br />
*<b>@keep()</b> retains the element in the anonymized object without modification of any of the elements in any of its item datasets.<br />
*<b>@remove()</b> removes the element and all its item datasets from the anonymized object.<br />
*<b>@process()</b> anonymizes all the item datasets of the element.<br />
<br />
When processing the root dataset, the anonymizer modifies existing elements in accordance with their scripts. It also creates new elements when instructed to do so by a script. When processing an item dataset, the anonymization scripts are used, but no new elements are allowed to be created. This feature must be kept in mind when coding the scripts for elements that are to be processed in item datasets to prevent the inadvertent creation of an element in the root dataset. Here is a contrived example to illustrate the point:<br />
<br />
Suppose the [0010,4000] PatientComments element appears in an SQ item and it is to be replaced with static text. One way to code the script for the element is:<br />
<br />
:<tt><b>new text</b></tt><br />
<br />
This will replace the contents of all PatientComments elements anywhere in the object, whether in the root dataset or in any processed SQ elements' item datasets. And if the element does not appear in the root dataset, this script will create it. To prevent this action, the <b>select</b> function should be used to distinguish the two cases. If the intent is not to modify the element if it appears in the root dataset, the script would then be:<br />
<br />
:<tt><b>@select(){@keep()}{new text}</b></tt><br />
<br />
Note that in the root clause, the <b>keep</b> function will keep the element if it exists, but it will not create it if it doesn't.<br />
<br />
As a further example, suppose the [0008,1155] RefSOPInstanceUID element appears in an SQ item and it is to be replaced with a hashed UID. Again, one way to code the script for the element is:<br />
<br />
:<tt><b>@hashuid(@UIDROOT,this)</b></tt><br />
<br />
As in the previous example, this will affect all RefSOPInstanceUID elements in the object, whether in the root dataset or in any processed SQ elements' item datasets. And as before, if the element does not appear in the root dataset, the anonymizer will try to create it. In this case, however, the missing element will <u>not</u> be created because of a unique feature of the <b>hashuid</b> function, which generates a <b>remove</b> function call if it fails. (It fails here because the <b>this</b> keyword refers to a non-existent element. The <b>remove</b> function call that is generated by the <b>hashuid</b> function does nothing here because the element doesn't exist.) Thus, the simple script above is protected from inadvertently creating elements.<br />
<br />
For scripts containing other function calls or scripts that replace element values with static text, the <b>select</b> function must be used to prevent the creation or modification of the element in the root dataset.<br />
<br />
When processing an item dataset, all references to elements are limited to the item dataset being processed. Thus, it is not possible to reference elements in the root dataset or in any other item dataset in the object.<br />
<br />
When processing an item dataset, all parameters are available. Thus, when hashing UIDs, the $UIDROOT parameter is available to ensure that all UIDs are created with the same root.<br />
<br />
==Advanced Configuration==<br />
===Extending the Anonymizer===<br />
The anonymizer can be extended to meet specialized requirements by editing the script file. A word to the wise: a certain amount of caution should be observed when editing powerful files.<br />
<br />
The script file is a text file that can be edited with any good text editor like TextPad. The content of the file is a set of properties, one per line, in the form:<br />
<br />
:<b>key = value</b><br />
<br />
Properties beginning with <b>#</b> are disabled. Do not remove disabled properties or the anonymizer configurator will lose knowledge of the property. The order of the lines in the file determines the order in which the anonymizer configurator presents them to the user. There are four basic kinds of keys:<br />
<br />
*Keys beginning with <b>param.</b> are parameters. Traditionally, parameter names are all in upper case and all the parameters are defined at the top of the file, but there is no programmatic requirement to do so. If you want to define additional parameters for use in the DICOM element scripts, you can add them by appending the parameter name to the prefix, like this:<br />
::<b>param.NEWPARAM = value</b><br />
<br />
:The <b>=</b> sign is required. The value is optional.<br />
*Keys beginning with <b>set.</b> provide replacement scripts for individual DICOM elements. Additional elements can be added. It is best to add them in sequence to make it easy to find them in the anonymizer configurator table, but there is no programmatic requirement to do so. Set keys have the form:<br />
<br />
::<b>set.[gggg,eeee]ElementName = value</b><br />
<br />
:The <b>ElementName</b> is traditionally the name recognized by the dcm4che DICOM class library for the element, although it is the <b>[group,element]</b> designation that determines which element is modified by the script. When adding an element for a private group, you can pick any name you wish, but scripts cannot reference the element by name. The value is optional.<br />
*Keys beginning with <b>keep.group</b> immediately followed by the hex value of a DICOM group number, as in <b>keep.group18</b>, are global <b>keep</b> commands. They do not contain scripts. To provide a label for the command in the anonymizer configurator, the value of the property can be supplied, like this:<br />
<br />
::<b>keep.group18 = Keep group 18 [recommended]</b><br />
<br />
:The standard <b>dicom-anonymizer.properties</b> file contains <b>keep</b> commands for groups 18, 20, and 28, and default label values for those groups are defined in the program. They may be overridden by specifying values in the script file. A typical use of this type of property is to provide a convenient way to keep a specific private group, but standard DICOM groups can be added as well. <br />
*Keys beginning with <b>remove.</b> are global <b>remove</b> commands. The anonymizer cannot be extended with <b>remove</b> commands.<br />
<br />
===Special Lookup Functions===<br />
The <b>lookup</b> function has two special features that can be useful in certain situations. These features are available in both versions of the function (<b>@lookup(ElementName,KeyType)</b> and <b>@lookup(ElementName,KeyType,action)</b>).<br />
<br />
The first special feature is that the <b>ElementName</b> argument can be a sequence of element names, separated by the pipe character ("|"). For example, consider this function call:<br />
<br />
:<b><tt>@lookup(PatientID|StudyDate,xyz,skip)</tt></b><br />
<br />
When processing an object with a PatientID of 23456 and a StudyDate of 20120825, the anonymizer will construct this key into the lookup table: <br />
<br />
:<b><tt>xyz/23456|20120825</tt></b>. <br />
<br />
This feature can be used to generate a replacement value only for specific combinations of elements. There is no limit to the number of elements that can be combined in this way.<br />
<br />
If the key that is generated does not appear in the lookup table, the anonymizer takes the action specified in the action argument, if present.<br />
<br />
The second special feature is that the lookup table has an indirection feature. If the value in the lookup table for a certain key starts with an at-sign ("@") and also contains a slash ("/"), then when the lookup occurs, the value (after removing the at-sign) is treated as a key and another lookup is done. This process is recursive, and it only stops when a retrieved value does not match an indirection key. (To prevent infinite loops, a limit of 10 indirection lookups is imposed.)<br />
<br />
As an example of the use of these features in the retrospective processing of clinical trial data, suppose it is desired to alter the StudyDate element for DicomObjects based on the PatientID and the StudyDate. Suppose that there are three replacement StudyDate values, 20010201, 20020201, and 20030201. The StudyDate element might be coded as shown above. The lookup table might be constructed like this:<br />
<br />
<tt><br />
:xyz/22|19980508 = @year/1<br><br />
:xyz/22|19990615 = @year/2<br><br />
:xyz/22|20000501 = @year/3<br><br />
:...similar rows for other patients<br />
:year/1 = 20010201<br><br />
:year/2 = 20020201<br><br />
:year/3 = 20030201<br><br />
</tt><br />
<br />
With this lookup table, the actual replacement dates can be specified in one place in the table, and through indirection, referenced from many places.<br />
<br />
The script shown above assumes that if an object doesn't have a matching entry in the lookup table, the object is not to be anonymized. In some situations, it might be desirable to allow other de-identification to be done in the object and just to keep the original value for the StudyDate. In that case, the StudyDate element would be coded as:<br />
<br />
:<b><tt>@lookup(PatientID|StudyDate,xyz,keep)</tt></b><br />
<br />
The <b>this</b> keyword can be used anywhere in the <b>ElementName</b> argument. For the example above, the code could have been:<br />
<br />
:<b><tt>@lookup(PatientID|this,xyz,skip)</tt></b><br />
<br />
==Precedence==<br />
It is possible to create a set of instructions that appear to be self-contradicting, so an instruction precedence is required. The principle for defining precedence is:<br />
#A command specific to an element takes precedence over global commands. <br />
#Global <b>keep</b> commands take precedence over global <b>remove</b> commands.<br />
<br />
Thus, if an element is part of a private group and private groups are to be removed, but the element has a script requiring it to be kept, it is kept.<br />
<br />
If an element is not selected (e.g., unchecked) and unchecked elements are to be globally removed, but the element is part of a group to be kept, it is kept.<br />
<br />
If an element that is part of a private group is not selected and private groups are to be globally removed, but the element’s group is to be kept, the element is kept.<br />
<br />
There is one exception to the principle: if overlays are to be globally removed, that command takes precedence over any <b>keep</b> commands that have been defined for individual overlay groups.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_TFS&diff=8031MIRC TFS2017-11-08T16:20:37Z<p>Johnperry: /* Java */</p>
<hr />
<div>This article describes the new version of the MIRC teaching file system (TFS) running as a plug-in on CTP. This article is intended for people interested in installing MIRC.<br />
<br />
===Background===<br />
MIRC - Medical Imaging Resource Center - is an RSNA project to provide tools for radiological teaching files and clinical trials. Beginning in 2000, the project has produced many software releases.<br />
<br />
The earliest versions of MIRC were restricted to Microsoft platforms, using IIS as the server (versions 1-9). Starting with version 10, MIRC was rewritten in Java to run on Tomcat. Those versions were denoted with the prefix <b>T</b> (T10-T36). <br />
<br />
The Tomcat-based versions supported both teaching files and clinical trials. In the clinical trials application, however, the extra complexity of the Tomcat installation was an impediment, so a special clinical trials application was developed called <b>CTP</b>. CTP contains its own embedded servlet container, providing the necessary capabilities from Tomcat without the need for a separate installation step. It also contains a more capable processing facility and anonymizers that implement the DICOM Supplement 142 de-identification profiles. For more information on CTP, see [[CTP-The RSNA Clinical Trial Processor]].<br />
<br />
As experience was gained with CTP, it became clear that it could serve as the servlet container for MIRC, providing both new features and simplified installation. To support MIRC, numerous extensions to CTP were implemented, the most important of which was the development of plug-ins, which provide processing capabilities outside the normal CTP pipelines. MIRC TFS is implemented as a single plug-in in this framework.<br />
<br />
In early 2012, the MIRC Committee changed the name of the teaching files application from MIRC to TFS. In the context of this article, MIRC and TFS are used as synonyms.<br />
<br />
The new MIRC TFS implementation is denoted with the <b>Z</b> prefix. The starting release identifier has been reset to <b>1</b>, so the first release is designated <b>Z1</b>.<br />
<br />
The CTP/MIRC TFS implementation is recommended for all new MIRC TFS installations.<br />
<br />
<br />
===Installation===<br />
<br />
Three components are required for running a MIRC TFS site under CTP:<br />
* Java<br />
* JAI ImageIO Tools<br />
* CTP and the MIRC TFS plug-in<br />
<br />
====Java====<br />
The Java 1.7 (or better) JRE must be present on the system. Java 1.8 is strongly recommended. Java is available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. <br />
<br />
:<em>When installing Java, make sure to obtain the 32-bit version, even if you are running on a 64-bit platform. Sophisticated users may be able to run the 64-bit versions on some platforms, but the gains would be minimal and the likelihood of encountering problems would be large.</em><br />
<br />
====JAI ImageIO Tools====<br />
MIRC requires that the [http://download.java.net/media/jai-imageio/builds/release/1.1/ Java Advanced Imaging ImageIO Tools] be present on the system. It is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. You must get the jre version (for Windows, it has a name like jai_imageio-1_1-lib-windows-i586-jre.exe), not the one for the CLASSPATH, which does not include <b>-jre</b> in the name. <br />
<br />
:<em>Note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required.</em><br />
<br />
====CTP/TFS====<br />
[[Image:MIRC-installer.jpg|thumb|right|400px]] The installer for MIRC TFS is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane to obtain a list of all the available software. The <b>TFS-installer</b> available on the site includes CTP and all the libraries required to run the teaching files application.<br />
<br />
Once Java and the ImageIO Tools are installed, download the installer and place it on the disk on which you intend to install or upgrade the CTP program. Do <b>not</b> run it without downloading it and storing it locally.<br />
<br />
:<em>For convenience, it is recommended (but not required) that a folder called </em><b><tt>JavaPrograms</tt></b><em> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP there. This is especially helpful during future upgrades.</em><br />
<br />
To run the TFS installer, double-click the <tt><b>TFS-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar TFS-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b><tt>CTP</tt></b> in the selected location and places several files and directories in it. <br />
<br />
When the installer runs, it checks several parameters of the system and highlights in red any components that are not correct for the running of CTP.<br />
<br clear="right"/><br />
<br />
===Running CTP with the MIRC TFS Plug-in===<br />
Note that TFS is not a stand-alone program; it is a plug-in to CTP in the same way that previous versions of MIRC were webapps that ran under Tomcat. Therefore, it is most correct to speak of running <b>CTP</b> rather than <b>TFS</b> or <b>MIRC</b>, so that terminology is used here.<br />
<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows or Linux service. See [[Running CTP as a Windows Service]] or [[Running CTP as a Linux Service]] for instructions. <br />
<br />
[[Image:CTP-launcher.jpg|thumb|right|400px]] The <b><tt>Launcher.jar</tt></b> program can be started by double-clicking the file or by launching a command window and entering the command:<br />
:<tt><b>java -jar Launcher.jar</b></tt><br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>TFS Home Page</b> button launches the user's browser and goes directly to the main TFS page.<br />
<br />
To stop the program, either click the <b><tt>Stop</tt></b> button on the dialog or log in as a user with the <tt>shutdown</tt> privilege and click the <b>Shutdown</b> item in the <b>Admin > CTP</b> menu on the main query page. As a convenience, a user with the <tt>admin</tt> privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br clear="right"/><br />
<br />
==Accessing TFS from the Network==<br />
When CTP starts, it loads the MIRC plug-in. The MIRC plug-in installs several servlets to provide access to the system. The query page serves as the portal into all the TFS features. Its URL is:<br />
:<b><tt>/query</tt></b><br />
<br />
Several other URLs also end up at the query page, but they do so by redirecting the browser, so it is most efficient to use the actual query page URL. Other URLs that go to the query page are:<br />
:<b><tt>/</tt></b><br />
:<b><tt>/mirc</tt></b><br />
<br />
==Server Configuration==<br />
[[Image:UserManager.jpg|thumb|right|400px]] When the program is first installed, two users are provided. One user, with the name <b><tt>admin</tt></b> and password <b><tt>password</tt></b>, is intended for general system administration. The other user, with the name <b><tt>king</tt></b> and password <b><tt>password</tt></b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user. Most MIRC administrators log in as the <b><tt>admin</tt></b> user.<br />
<br />
After installing and starting CTP and MIRC TFS, access the query page, click the <b>Login</b> button to log in as the <b><tt>admin</tt></b> user, and then go to the <b>Admin > User Manager</b> menu item. This will display a page allowing you to add and modify users. To start, check all the boxes in the <b>admin</b> user except <b>shutdown</b> and then click the save icon in the upper right corner of the page. The page will re-display, showing that the changes have been made. You should change the passwords of these accounts at this time as well, using the unlabelled column at the right side of the table. If you need to create accounts for other users, use the blank line at the bottom of the table. Each time the save icon is clicked, a new blank line will appear. When all the changes have been made, click the home icon in the upper right corner of the page to go back to the query page.<br />
<br clear="right"/><br />
<br />
TFS has two user interfaces, the <b>Classic UI</b> and the <b>Integrated UI</b>. These present almost the same functionality in two different ways. Each only shows the user those functions that the user's privileges allow him to access.<br />
<br />
::[[Image:ClassicUI.jpg|400px|Classic UI]] [[Image:IntegratedUI.jpg|400px|Integrated UI]]<br />
<br />
Individual users can choose their preferred UI and switch between them easily. As the administrator, you can choose the default UI to be presented to an unauthenticated user. To do so, go to the <b>Admin > Query Service Admin</b> menu item. On that page, select the desired radio button in the <b>Default query page user interface</b> field and then click the save button:<br />
<br />
[[Image:QSAdmin.jpg|center|500px]] <br />
<br />
On the Query Service Admin page, you can also control which other TFS sites are available to be queried. After making any changes, click the save icon and then click the home icon to return to the main query page.<br />
<br />
At this point, the site is ready for operation.<br />
<br />
==Client Configuration for Document Authoring==<br />
TFS provides authoring tools to create MIRCdocuments that are accessed through the user's browser. <br />
<br />
When authoring a MIRCdocument, a special SVG viewer must be installed on the author's computer to allow images to be annotated. The free Adobe SVG viewer can be obtained from [http://www.adobe.com/svg/viewer/install/main.html the Adobe SVG Site]. Adobe no longer supports the SVG viewer, but it works just fine. At the bottom of the Adobe page, there is a table of versions for different operating systems. Adobe hasn’t updated the page since the late Pleistocene, and the last Windows version listed is XP, but it has been tested successfully on Vista and Windows 7 using IE7, 8, and 9, as well as the latest Firefox and Chrome.<br />
<br />
The SVG viewer is not required for displaying annotated images, only for creating the annotations themselves, so the viewer need only be installed on computers used by authors who wish to create annotations.<br />
<br />
==Advanced Configuration==<br />
In addition to plugins like the one that implements MIRC TFS, CTP supports sequences of processing steps called pipelines. Pipelines are described in [[CTP-The RSNA Clinical Trial Processor]]. MIRC employs pipelines to support the reception of DICOM images for the File Service, the DICOM Service, and the TCE Service. The MIRC pipelines are described in [[MIRC Pipelines]]. <br />
Each service pipeline has its own DICOM Storage SCP. The default ports for these SCPs are:<br />
* File Service: port 1081<br />
* DICOM Service: port 1082<br />
* TCE Service: port 1083.<br />
These ports can be changed to any unused ports on the system. After starting CTP/MIRC for the first time, click the <b>Log</b> button on the <b><tt>CTP-launcher</tt></b> dialog and see if there are any log entries indicating that an address was already in use. If so, see the [[MIRC Pipelines]] article and move the offending service to another port.<br />
<br />
==Using LDAP for Authentication==<br />
CTP can be configured to support LDAP for user authentication. See [[CTP Authentication Using LDAP]] for details.<br />
<br />
==Using OpenAM for Authentication==<br />
CTP can be configured to support OpenAM for user authentication. See [[CTP Authentication Using OpenAM]] for details.<br />
<br />
==Upgrading a Tomcat MIRC Site==<br />
To upgrade from the Tomcat MIRC implementation to the CTP MIRC implementation, there are two steps:<br />
* create a fresh installation of CTP MIRC<br />
* copy the existing Tomcat MIRC site to the CTP MIRC site.<br />
<br />
To assist in copying the old site to the new one, the CTP MIRC installation includes a program called <b><tt>Copier.jar</tt></b> in the <b><tt>CTP</tt></b> directory. To run the program, double-click the file or start it with the command:<br />
:<b><tt>java -jar Copier.jar</tt></b><br />
<br />
The <b><tt>Copier</tt></b> program can be run while the Tomcat MIRC site is running. The Tomcat MIRC site is not modified in any way.<br />
<br />
If the <b><tt>Copier</tt></b> program is run while the CTP MIRC site is running, it automatically stops the site.<br />
<br />
The <b><tt>Copier</tt></b> program copies:<br />
* the users' accounts<br />
* the users' names, affiliations, and contact information<br />
* the storage services:<br />
** all the MIRCdocuments<br />
** the settings:<br />
*** Storage Service tagline<br />
*** Author Service enable<br />
*** Submit Service enable<br />
*** Zip Service enable<br />
*** DICOM Service enable<br />
*** TCE Service enable<br />
*** autoindex enable<br />
*** maximum upload size<br />
*** JPEG quality parameter<br />
*** deleted documents timeout<br />
<br />
The following information is <u>not</u> copied:<br />
* the users' file cabinets<br />
* the shared file cabinet<br />
* the users' conferences<br />
* the shared conferences<br />
<br />
Notes: <br />
* If a user already exists in the CTP site, that user is not modified.<br />
* When copying a storage service, the program tries to find an existing storage service with the same name. If it finds one, it adds the documents to the existing storage service. If it does not find one, it creates a new storage service.<br />
* The program can be run multiple times without creating duplicate user accounts, storage services, or MIRCdocuments.<br />
* When the CTP MIRC site is first installed, one empty storage service is automatically provided. After copying from the Tomcat site to the CTP site, this storage service may still be empty. If you want to remove it, go to the Storage Service admin page and click the <b>Remove this Storage Service</b> button.</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=Using_the_DicomAnonymizer_dateinterval_Function&diff=8030Using the DicomAnonymizer dateinterval Function2017-10-30T14:53:00Z<p>Johnperry: </p>
<hr />
<div>This article describes how to configure the DICOM anonymizer to use the <b>dateinterval</b> function. The intended audience for this information is clinical trial coordinators.<br />
<br />
The DicomAnonymizer <b>dateinterval</b> function computes the number of days between two dates, typically a StudyDate and a base date associated with the PatientID and stored in the anonymizer's lookup table.<br />
<br />
The function can have three or four arguments:<br />
<br />
*<b>DateElementName</b> specifies the date element in the DICOM dataset to serve as the end of the interval.<br />
*<b>KeyType</b> specifies the subset of the lookup table containing base dates.<br />
*<b>KeyElementName</b> specifies the element in the DICOM dataset to serve as the key under which to find the base date of the interval.<br />
*<b>OriginDate</b> specifies a date to which the computed number of days is added before returning the resulting date.<br />
<br />
DICOM date elements have the format <b><tt>YYYYMMDD</tt></b>. The format used for base dates in the lookup table is the more conventional <b><tt>M/D/YYYY</tt></b>, as in 7/4/1776 or 12/25/2017. The OriginDate argument, if present, must be in DICOM format. The OriginDate argument may be supplied as a parameter reference.<br />
<br />
The function subtracts the base date from the DateElement value and converts the result to days.<br />
<br />
If the OriginDate argument is not supplied, the function returns the computed interval in days.<br />
<br />
If the OriginDate argument is supplied, the function adds the computed number of days to the OriginDate and returns the resulting date in DICOM format.<br />
<br />
For example, if it is desired to store the date interval in an element during the anonymization process, the script for the element might be written as:<br />
<br />
:<tt><b>@always()@dateinterval(StudyDate,basedate,PatientID)</b></tt><br />
<br />
In this example, the KeyType is specified as <b>basedate</b>, but it could be any single-word text. <br />
<br />
As another example, if it is desired to create dates starting from some origin in time, offset by the computed interval, and store the date interval in an element during the anonymization process, the script for the element might be written as:<br />
<br />
:<tt><b>@always()@dateinterval(StudyDate,basedate,PatientID,20000101)</b></tt><br />
<br />
In this example, the OriginDate is specified in the function call itself, but if several elements are to be offset in this way, it would be more convenient to specify the OriginDate as a parameter reference (e.g., @ORIGINDATE). <br />
<br />
Note: the <b>@always()</b> function call is required to force the creation of the element if it is not already present in the data object.<br />
<br />
If the base date is not present in the lookup table, the DicomAnonymizer will quarantine the object.<br />
<br />
A more convenient way to trap objects for which the base date is missing is to put a LookupTableChecker pipeline stage before the DicomAnonymizer. Here is a configuration illustrating how to do it:<br />
<br />
<pre><br />
<Configuration><br />
<Server<br />
maxThreads="20"<br />
port="9666"/><br />
<Pipeline<br />
name="Test Pipeline"<br />
root="test"><br />
<DicomImportService<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
logConnections="no"<br />
name="DicomImportService"<br />
port="104"<br />
quarantine="quarantines/DicomImportService"<br />
root="roots/DicomImportService"/><br />
<LookupTableChecker<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
id="LookupTableChecker"<br />
name="LookupTableChecker"<br />
quarantine="quarantines/LookupTableChecker"<br />
root="roots/LookupTableChecker"/><br />
<DicomAnonymizer<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
lookupTable="scripts/LookupTable.properties"<br />
name="DicomAnonymizer"<br />
quarantine="quarantines/DicomAnonymizer"<br />
root="roots/DicomAnonymizer"<br />
script="scripts/DicomAnonymizer.script"/><br />
<FileStorageService<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
name="FileStorageService"<br />
port="9667"<br />
quarantine="quarantines/FileStorageService"<br />
returnStoredFile="yes"<br />
root="roots/FileStorageService"/><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
When an object is encountered that will cause a <b>lookup</b> or <b>dateinterval</b> function call in the anonymization script to quarantine the object, the LookupTableChecker will put the object in its quarantine and make an index entry in its database identifying the offending elements. The LookupTableChecker servlet provides a convenient user interface to allow the table to be updated, after which the user can view the quarantine contents and click the <b>Queue All</b> button to process the quarantined objects. The LookupTableChecker stage provides access to its database and quarantine through its status page, which is available by clicking the stage in the left pane of the CTP home page.<br />
<br />
Note: The <b>id</b> attribute of the LookupTableChecker stage is used to specify the context of the LookupTableChecker servlet, so in configurations with multiple LookupTableChecker stages (as might occur in multi-pipeline configurations), it is necessary to ensure that the <b>id</b> attributes are unique; otherwise, only the last stage that claimed the <b>id</b> attribute will be visible to the user interface (although all the LookupTableChecker stages will properly check objects and quarantine them as necessary).</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8029MIRC CTP2017-10-22T12:52:59Z<p>Johnperry: /* DirectoryImportService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the import directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the import directory.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
* The patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8028MIRC CTP2017-10-22T12:51:34Z<p>Johnperry: /* ArchiveImportService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified as a DICOM keyword or in hex, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
* The patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8027MIRC CTP2017-10-22T12:49:00Z<p>Johnperry: /* DirectoryImportService */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
* The patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=Configuring_the_CTPClient_Application_for_Clinical_Trials&diff=8026Configuring the CTPClient Application for Clinical Trials2017-09-13T14:28:34Z<p>Johnperry: /* Local */</p>
<hr />
<div>The CTPClient application is a program for anonymizing images and transmitting them from image acquisition sites to principal investigator sites in clinical trials. This article describes how to configure, distribute, and run the program. The intended audience for this article is clinical trial administrators and their software minions.<br />
<br />
==Running CTPClient==<br />
CTPClient can be launched via the Java webstart mechanism, thus removing the necessity for installing CTP applications at the image acquisition sites. When run via webstart, the user accesses a URL on the principal investigator's CTP site, and the browser downloads CTPClient and starts it. The recommended method for launching CTPClient via webstart is to use the CTP Application Server on the CTP site. For general information on the Application Server, see [[Using the CTP Application Server]].<br />
<br />
CTPClient can also be launched as a stand-alone application installed on the client computer. When run stand-alone, the program is started by double-clicking the program's icon or by launching a command window and entering the command:<br />
<br />
:<b><tt>java -jar CTPClient.jar [options]</tt></b><br />
<br />
where [options] is a series of quoted parameters, each in the form:<br />
<br />
:<b><tt>"param=value"</tt></b><br />
<br />
==The Processing Pipeline==<br />
===Import Services===<br />
CTPClient has two import mechanisms.<br />
* Locally stored files can be manually selected.<br />
* A DICOM Storage SCP can be enabled to receive files from PACS systems or workstations.<br />
<br />
===Processing Stages===<br />
CTPClient has a fixed processing pipeline consisting of these stages, in this order:<br />
* DicomFilter<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomAnonymizer<br />
<br />
The DicomFilter and DicomPixelAnonymizer stages must be explicitly enabled using the parameters described in the next section. The DicomDecompressor stage is run <u>only if</u> the object being processed matches a signature of the DicomPixelAnonymizer; otherwise, the object is not decompressed. See [[The CTP DICOM Pixel Anonymizer]] for more information.<br />
<br />
The DicomAnonymizer is always enabled.<br />
<br />
No default script is provided for the DicomFilter.<br />
<br />
Default scripts are provided for the DicomPixelAnonymizer and the DicomAnonymizer. <br />
<br />
No default lookup table is provided for the DicomAnonymizer.<br />
<br />
===ExportServices===<br />
CTPClient has three export services:<br />
* HttpExportService<br />
* DicomExportService<br />
* DirectoryStorageService<br />
<br />
==Run-time Configuration==<br />
CTPClient is designed to be configured by setting the [options] parameters for the transmitting site. When run via webstart, these parameters can be supplied by query parameters in the URL, as in this example:<br />
<br />
:<b><tt>http://ctp.university.edu/webstart/CTPClient?param1=value1&param2=value2</tt></b><br />
<br />
Note that when a value includes whitespace or any other characters that are illegal in a URL, the value must be URL-encoded.<br />
<br />
As mentioned in [[#Building CTPClient|Building CTPClient]], below, a special CTPClient build can be created for specific applications, including application-specific files and configuration parameters.<br />
<br />
===Configuration Parameters===<br />
The parameters supported by the program are shown below.<br />
<br />
====Window Display Parameters====<br />
*<b><tt><font size=4>windowTitle</font></tt></b>: The text to be shown in the title bar of the CTP Client window. The default is "CTP Client".<br />
*<b><tt><font size=4>panelTitle</font></tt></b>: The text to be shown at the top of the main pane in the CTPClient UI. The default is "CTP Client".<br />
*<b><tt><font size=4>helpURL</font></tt></b>: The URL to be accessed when the user clicks the Help button on the CTPClient UI. If this parameter is missing, the Help button is not displayed.<br />
<br />
====Import Service Parameters====<br />
*<b><tt><font size=4>showBrowseButton</font></tt></b>: Specifies whether to display a button allowing the user to browse the local disk for images to display. If an scpPort is defined and the showBrowseButton parameter is set to "no", a browse button is not displayed. If the parameter is set to any other value, the dialog button is displayed, whether an scpPort parameter is supplied or not. <br />
*<b><tt><font size=4>scpPort</font></tt></b>: The port on which CTPClient is to start a DICOM Storage SCP to receive objects via the DICOM protocol. If set to any integer greater than zero, CTPClient starts the SCP and accepts transfers from DICOM Storage SCUs. If the parameter is not supplied, or if it is blank or a non-integer value, the SCP is disabled. The default configuration does not enable the SCP.<br />
*<b><tt><font size=4>acceptNonImageObjects</font></tt></b>: Specifies whether non-image objects are to be selected for processing. If set to "yes", all objects are accepted. If set to any other value, only images are accepted. The default configuration only accepts image objects.<br />
*<b><tt><font size=4>dialogEnabled</font></tt></b>: Specifies whether to provide a dialog for entry of parameters at runtime. If set to "yes", a dialog is constructed from definitions in an XML file. If set to any other value, no dialog is provided.<br />
*<b><tt><font size=4>dialogName</font></tt></b>: The name of an XML file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. If the file is not found on the server, CTPClient looks for the file in the same directory in which the program is running. If that fails, CTPClient looks for the default dialog file built into the application (<b><tt>DIALOG.xml</tt></b>). If the XML file cannot be found, the dialog is disabled, even if the dialogEnabled parameter is set to "yes". Values provided by the user in the dialog are treated as if they were options included in the start command of the program. {See [[#The Dialog XML Schema|The Dialog XML Schema]] for a description of how to configure the dialog.) <br />
*<b><tt><font size=4>showDialogButton</font></tt></b>: Specifies whether to display a button allowing the user to display the dialog. If set to "no", a dialog button is not displayed. If set to any other value, the dialog button is displayed.<br />
<br />
====Processing Pipeline Parameters====<br />
*<b><tt><font size=4>dfEnabled</font></tt></b>: Specifies whether to use the DicomFilter to select objects for processing. If set to "yes", objects are selected using the DicomFilter script. If set to any other value, no filtering is done.<br />
*<b><tt><font size=4>dfScriptName</font></tt></b>: The name of a DicomFilter script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient looks for the default script (<b><tt>DF.script</tt></b>) built into the application. If no default script is found, the DicomFilter stage is disabled, even if the dfEnabled parameter is set to "yes".<br />
*<b><tt><font size=4>dpaEnabled</font></tt></b>: Specifies whether the DicomPixelAnonymizer is to be included in the processing of objects. If set to "yes", objects are processed using the DicomPixelAnonymizer script. If set to any other value, no pixel anonymization is done.<br />
*<b><tt><font size=4>dpaScriptName</font></tt></b>: The name of a DicomPixelAnonymizer script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient looks for the default script (<b><tt>DPA.script</tt></b>) built into the application. If no default script is found, the DicomPixelAnonymizer stage is disabled, even if the dpaEnabled parameter is set to "yes".<br />
*<b><tt><font size=4>setBurnedInAnnotation</font></tt></b>: Specifies whether the BurnedInAnnotation element is to be set to "NO" for DICOM objects that match a DicomPixelAnonymizer signature. If set to "yes", the element value is set, if the parameter is missing or has any other value, the element is not modified. <br />
*<b><tt><font size=4>daScriptName</font></tt></b>: The name of a DicomAnonymizer script file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the script file from the server. When not present, CTPClient uses the default script (<b><tt>DA.script</tt></b>) built into the application.<br />
*<b><tt><font size=4>daLUTName</font></tt></b>: The name of a DicomAnonymizer lookup table file stored on the CTP server in the same directory as the CTPClient being served by the Application Server. When present, CTPClient downloads the lookup table file from the server. When not present, CTPClient looks for the default lookup table (<b><tt>LUT.properties</tt></b>) built into the application. If no lookup table is available, an empty lookup table is provided.<br />
<br />
In addition to the standard parameters above, CTPClient supports special parameters for modifying the DicomAnonymizer script parameters and lookup table entries. <br />
<br />
Any parameter name starting with the at-sign ( '@' ) is treated as an anonymizer script modification. The '@' is removed, and the rest of the parameter name is used as the name of a script PARAM. The parameter value (the text after the '=' character) is used as the value for that PARAM. The intent of this feature is to allow a standard script to be tailored for a specific image acquisition site. Note that this feature does not allow element scripts to be modified; it only allows script PARAM values to be changed.<br />
<br />
Any parameter name starting with the dollar-sign ( '$' ) is treated as a lookup table modification. The '$' is removed, and the rest of the parameter name is used as the lookup table key. The parameter value (the text after the '=' character) is used as the value for that key. The intent of this feature is to allow a standard lookup table to be tailored for a specific image acquisition site.<br />
<br />
For more information on anonymizer parameters and lookup tables, see [[The CTP DICOM Anonymizer]], [[The CTP DICOM Anonymizer Configurator]], and [[The CTP Lookup Table Editor]].<br />
<br />
====Export Service Parameters====<br />
*<b><tt><font size=4>httpURL</font></tt></b>: The URL of the destination HttpImportService. If this parameter is not supplied, or if it is blank, the HttpExportService is disabled. This parameter must be a complete URL, including the protocol (http://IP:port or https://IP:port).<br />
*<b><tt><font size=4>showURL</font></tt></b>: "yes" to display a UI field for entering the URL of the destination HttpImportService. "no" to suppress the UI field, thus forcing the URL to be the value of the <b><tt>httpURL</tt></b> parameter. The default value is "yes".<br />
*<b><tt><font size=4>zip</font></tt></b>: "yes" to zip files before transmission via HTTP. The default value is "no". This feature is intended only for transmissions to a CTP site with an HttpImportService configured with a zip parameter set to "yes".<br />
*<b><tt><font size=4>dicomURL</font></tt></b>: The URL of the destination DICOM Storage SCP (e.g. PACS or workstation). If this parameter is not supplied, or if it is blank, the DicomExportService is disabled. This parameter must be a complete URL, including the protocol (e.g. dicom://CalledAET:CallingAET@IP:port).<br />
*<b><tt><font size=4>stowURL</font></tt></b>: The URL of the destination DICOM STOW-RS Service. If this parameter is not supplied, or if it is blank, the DicomSTOWRSExportService is disabled. This parameter must be a complete URL, including the protocol (e.g. http://ip:port).<br />
*<b><tt><font size=4>stowUsername</font></tt></b>: The username to be used when authenticating with the destination DICOM STOW-RS Service. If this parameter is not supplied, or if it is blank, authentication credentials are not supplied when transferring to the destination system.<br />
*<b><tt><font size=4>stowPassword</font></tt></b>: The password to be used when authenticating with the destination DICOM STOW-RS Service.<br />
*<b><tt><font size=4>exportDirectory</font></tt></b>: The path to a directory in which processed files are to be stored. Files are stored with names constructed from their SOPInstanceUIDs. If this parameter is not supplied, or if it is blank, the DirectoryStorageService is disabled.<br />
*<b><tt><font size=4>renameFiles</font></tt></b>: Whether to rename exported files in the form Study_Series_Acquisition_Instance.dcm. If this parameter is not supplied, or if its value is not "yes", files are named by their SOPInstanceUID values.<br />
<br />
Note: If CTPClient is configured to export to an HTTP destination that requires authentication, the credentials can be included in the httpURL parameter like this: http://username:password@IPAddress:port. If the credentials are omitted from the URL and the destination requires them, CTPClient displays a dialog allowing the user to enter the credentials at the time of transmission.<br />
<br />
====Webstart Parameters====<br />
The Application Server supplies three parameters automatically when starting CTPClient. These are used by CTPClient to contact the server when the <b><tt>dfScriptName</tt></b>, <b><tt>dpaScriptName</tt></b>, <b><tt>daScriptName</tt></b>, or <b><tt>daLUTName</tt></b> parameters are supplied. If CTPClient is not started via webstart and the project requires that files be obtained from a server, the three parameters below must be supplied explicitly.<br />
<br />
*<b><tt><font size=4>protocol</font></tt></b>: The protocol to be used for communication with the CTP site's web server.<br />
*<b><tt><font size=4>host</font></tt></b>: The host IP address or domain name (and port) of the CTP site's web server.<br />
*<b><tt><font size=4>application</font></tt></b>: The name of the application ("<b><tt>CTPClient</tt></b>").<br />
<br />
====Debugging Parameters====<br />
When processing very large (typically multi-frame) objects, it may be necessary to allocate more than the default memory to the application using the <b><tt>max-heap-size</tt></b> attribute described in [[Using the CTP Application Server]]. To make it easy to see how much memory is in use, a button can be displayed in the application's window footer bar by enabling the <b><tt>showMemory</tt></b> parameter.<br />
*<b><tt><font size=4>showMemory</font></tt></b>: "yes" to display the button. The default is "no".<br />
<br />
===Default Configuration===<br />
====Webstart====<br />
For CTPClient instances that are run via Java webstart, it is possible to predefine parameter values in the <tt><b>CTPClient.xsl</b></tt> file stored on the server. This file will be located under the <tt><b>CTP/ROOT</b></tt> directory, typically in a first-generation child called CTPClient, although it is possible to locate it at a lower level, as in <tt><b>CTP/ROOT/MyTrial/CTPClient</b></tt>. The standard <tt><b>CTPClient.xsl</b></tt> file looks like this:<br />
<br />
<pre><br />
<?xml version="1.0" encoding="iso-8859-1"?><br />
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><br />
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" /><br />
<br />
<xsl:template match="/jnlp"><br />
<jnlp<br />
codebase="{environment/protocol}://{environment/host}/{environment/application}" ><br />
<!-- href="{environment/application}.jnlp" > --><br />
<br />
<information><br />
<title>CTP Client Utility</title><br />
<vendor>RSNA</vendor><br />
<homepage href="http://mircwiki.rsna.org/index.php?title=CTP-The_RSNA_Clinical_Trial_Processor"/><br />
<description>CTP Client Utility</description><br />
<description kind="short">Java Web Start program for transmitting data to CTP for clinical trials.</description><br />
<!-- <offline-allowed/> --><br />
</information><br />
<br />
<security><br />
<all-permissions/><br />
</security><br />
<br />
<resources><br />
<j2se version="1.6+"/><br />
<jar href="CTPClient.jar"/><br />
<jar href="CTP.jar"/><br />
<jar href="dcm4che.jar"/><br />
<jar href="dcm4che-imageio-rle-2.0.25.jar"/><br />
<jar href="jdbm.jar"/><br />
<jar href="log4j.jar"/><br />
<jar href="util.jar"/><br />
</resources><br />
<br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</jnlp><br />
</xsl:template><br />
<br />
<xsl:template match="param"><br />
<argument>"<xsl:value-of select="."/>"</argument><br />
</xsl:template><br />
<br />
</xsl:stylesheet><br />
</pre><br />
<br />
To predefine parameters, add <tt><b>argument</b></tt> elements to the <tt><b>application-desc</b></tt> element like this:<br />
<br />
<pre><br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<argument>"name1=value1"</argument><br />
<argument>"name2=value2"</argument><br />
<argument>"name3=value3"</argument><br />
...etc...<br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</pre><br />
<br />
For example:<br />
<br />
<pre><br />
<application-desc main-class="client.CTPClient"><br />
<argument>"protocol=<xsl:value-of select="environment/protocol"/>"</argument><br />
<argument>"host=<xsl:value-of select="environment/host"/>"</argument><br />
<argument>"application=<xsl:value-of select="environment/application"/>"</argument><br />
<argument>"panelTitle=My Trial CTP Client"</argument><br />
<argument>"showBrowseButton=yes"</argument><br />
<argument>"dialogName=DIALOG.xml"</argument><br />
<argument>"httpURL=http://theURL:80"</argument><br />
<argument>"showURL=yes"</argument><br />
<argument>"daScriptName=CTPClient.script"</argument><br />
<xsl:apply-templates select="params/param"/><br />
</application-desc><br />
</pre><br />
<br />
Note that by placing the predefined parameters before the <tt><b>xsl:apply-templates</b></tt> instruction, any parameters that are included in the URL itself will override the defaults.<br />
<br />
====Local====<br />
For CTPClient instances that are installed locally, it is possible to predefine parameter values in a properties file. The file must be called <tt><b>config.default</b></tt>, and it must be stored in the same directory as CTPClient.jar. Here is an example:<br />
<br />
<pre><br />
windowTitle=My Trial<br />
PanelTitle=My Trial<br />
helpURL=http://ctp.myUniversity.edu/myTrial/help.html<br />
dialogEnabled=yes<br />
dialogName=myTrialDialog.xml<br />
showDialogButton=no<br />
dfEnabled=no<br />
dpaEnabled=yes<br />
daScriptName=myTrialDAScript.script<br />
httpURL=http://ctp.PrincipalInvestigator.org:9999<br />
showURL=no<br />
showBrowseButton=yes<br />
</pre><br />
<br />
Properties files use the backslash character for escaping special characters, so if a backslash character is required in a property, it must be escaped by a backslash. Even on a Windows system, forward slashes work in specifying file paths in property values.<br />
<br />
==The Dialog XML Schema==<br />
When the <b><tt>dialogEnabled</tt></b> parameter is set to "yes", CTPClient loads an XML file to define the contents of a dialog allowing the user to enter values for parameters. The following is an example XML structure specifying three parameters:<br />
<br />
<pre><br />
<dialog title="New Patient" mode="study"><br />
<h>Site Parameters</h><br />
<p><br />
Enter the ID value for this site.<br />
</p><br />
<param<br />
name="@SITEID"<br />
label="Site ID"<br />
value=""/><br />
<h>Patient Parameters</h><br />
<p><br />
Enter the ID and name values for this patient.<br />
</p><br />
<param<br />
name="@SUBJECTID"<br />
label="Subject ID"<br />
value=""/><br />
<param<br />
name="@SUBJECTNAME"<br />
label="Subject Name"<br />
value=""/><br />
</dialog><br />
</pre><br />
<br />
The <b><tt>title</tt></b> attribute of the root element specifies the title of the popup. The title is also used as the name of the button in the main CTPClient window for displaying the dialog, so it should be fairly short.<br />
<br />
The <b><tt>mode</tt></b> attribute of the root element specifies the whether the dialog is to be displayed once for each study transmitted ("study" mode) or once for each click of the Start button ("session" mode). The default is study mode.<br />
<br />
The <b><tt>h</tt></b> element specifies a heading. The element has one optional attribute, <b><tt>align</tt></b>, with allowed values <b><tt>left</tt></b>, <b><tt>center</tt></b>, and <b><tt>right</tt></b>, The default is <b><tt>center</tt></b>.<br />
<br />
The <b><tt>p</tt></b> element specifies a paragraph. Word wrapping is not provided; lines are broken at newline characters. The element has one optional attribute, <b><tt>align</tt></b>, with allowed values <b><tt>left</tt></b>, <b><tt>center</tt></b>, and <b><tt>right</tt></b>, The default is <b><tt>left</tt></b>.<br />
<br />
The <b><tt>param</tt></b> element specifies a parameter whose value is to be entered into the dialog by the user. <br />
* The <b><tt>name</tt></b> attribute specifies the name of an option parameter.<br />
* The <b><tt>label</tt></b> attribute specifies the text to be displayed beside the entry field for the parameter.<br />
* The <b><tt>value</tt></b> attribute specifies the initial value provided in the entry field. If a value was provided by an option parameter when CTPClient was started, that value takes precedence over the value of the <b><tt>value</tt></b> attribute.<br />
<br />
Parameter names starting with <b><tt>@</tt></b> specify PARAM values in DicomAnonymizer scripts.<br />
<br />
Parameter names starting with <b><tt>$</tt></b> specify values in DicomAnonymizer lookup tables.<br />
<br />
The <b><tt>param</tt></b> element has an optional <b><tt>readonly</tt></b> attribute. When set to <b><tt>yes</tt></b>, the entry in the table is not editable. <br />
*If the <b><tt>name</tt></b> attribute is specified and the <b><tt>value</tt></b> attribute is missing or blank, the text displayed is the value of the specified configuration parameter.<br />
*If the <b><tt>value</tt></b> attribute is not blank, it takes precedence over any configuration parameter specified by the <b><tt>name</tt></b> attribute.<br />
*Examples:<br />
<pre><br />
<param<br />
name="@SITEID"<br />
label="Site ID:"<br />
readonly="yes"/><br />
<param<br />
label="Note:"<br />
value="Some readonly text"<br />
readonly="yes"/><br />
</pre><br />
<br />
==Building CTPClient==<br />
In some trials, it may be desired to build a special version of CTPClient with pre-configured values in the configuration files.<br />
<br />
The source code for CTPClient is on GitHub at https://github.com/johnperry/CTPClient.<br />
<br />
The default configuration files are located in the <b><tt>source/files</tt></b> directory:<br />
* <b><tt>config.properties</tt></b><br />
* <b><tt>DPA.script</tt></b><br />
* <b><tt>DA.script</tt></b><br />
<br />
In special situations, default files for the dialog, DicomFilter and DicomAnonymizer lookup table can be provided. The following are the names required by the application:<br />
<br />
* <b><tt>DIALOG.xml</tt></b><br />
* <b><tt>DF.script</tt></b><br />
* <b><tt>LUT.properties</tt></b><br />
<br />
The program is built using <b><tt>ant</tt></b>. After the build is complete, a zip file containing all the files necessary for deployment is located in the <b><tt>products</tt></b> directory.<br />
<br />
==Deploying CTPClient on the CTP Application Server==<br />
As described in [[Using the CTP Application Server]], all the files for CTPClient must be placed in the <b><tt>CTP/ROOT/CTPClient</tt></b> directory. The latest version is encapsulated in a zip file on the RSNA MIRC site at http://mirc.rsna.org/download/CTPClient.zip. <br />
<br />
Included in the zip file is the XSL file required by the Application Server for automatic creation of the webstart <b><tt>jnlp</tt></b> file.<br />
<br />
To deploy CTPClient, create the CTP/ROOT/CTPClient directory and copy all the files from the zip file into it.<br />
<br />
Note: If multiple CTPClient instances are to be supported in one CTP instance, install them in subdirectories of the ROOT directory, like this:<br />
<br />
:ROOT<br />
::TrialX<br />
:::CTPClient<br />
::TrialY<br />
:::CTPClient<br />
::TrialZ<br />
:::CTPClient<br />
<br />
In this situation, the URL to access a trial's CTPClient would include the trial name in the webstart path (e.g. /webstart/TrialY/CTPClient[?params]).</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8025MIRC CTP2017-08-30T15:35:43Z<p>Johnperry: /* Running CTP */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
When learning to use CTP or when developing a new pipeline configuration, it is best to start by running CTP from the Launcher.<br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
* The patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperryhttp://mircwiki.rsna.org/index.php?title=MIRC_CTP&diff=8024MIRC CTP2017-08-30T15:33:02Z<p>Johnperry: /* Installation */</p>
<hr />
<div>{| align="right"<br />
| __TOC__<br />
|}<br />
This article describes the RSNA MIRC Clinical Trials Processor (CTP), a stand-alone image processing application for imaging clinical trials data.<br />
<br />
==Clinical Trial Processor (CTP)==<br />
CTP is a stand-alone program that provides all the processing features of a MIRC site for clinical trials in a highly configurable and extensible application. It connects to FieldCenter applications and can also connect to MIRC sites when necessary. CTP has the following key features:<br />
#Single-click installation.<br />
#Support for multiple pipelines.<br />
#Processing pipelines supporting multiple configurable stages.<br />
#Support for multiple quarantines for data objects which are rejected during processing.<br />
#Pre-defined implementations for key components:<br />
#*HTTP Import<br />
#*DICOM Import<br />
#*DICOM Anonymizer<br />
#*XML Anonymizer<br />
#*File Storage<br />
#*Database Export<br />
#*HTTP Export<br />
#*DICOM Export<br />
#*FTP Export<br />
#Web-based monitoring of the application's status, including:<br />
#*configuration<br />
#*logs<br />
#*quarantines<br />
#*status<br />
<br />
===Installation===<br />
The installer for CTP is available on the [http://mirc.rsna.org RSNA MIRC site]. Click the <b>Download Software</b> link in the left pane of the MIRC home page to obtain a list of all the available software.<br />
<br />
Download the installer and place it on the disk on which you intend to install or upgrade the CTP program.<br />
<br />
To run the installer, the Java 1.7 (or better) JRE must be present on the system. Java 1.8 is recommended because earlier versions are being sunset by Oracle/Sun. Java and all its components are available through the [http://www.oracle.com/technetwork/java/javase/downloads/index.html Java] website. Note that only the JRE is required, not the JDK. If you plan to run CTP as a Windows service or if you plan to use the <b>Java Advanced Imaging ImageIO Tools</b> (see below), then you must install the 32-bit Java, even on a 64-bit computer.<br />
<br />
For convenience, it is recommended (but not required) that a folder called <b>JavaPrograms</b> be created in the root of the disk drive. The installer does not create this folder, but if it is present, the installer will very quickly find it and suggest installing CTP in a subdirectory of <b>JavaPrograms</b>. This is especially helpful when upgrading.<br />
<br />
Certain CTP pipeline stages (FileStorageService, BasicFileStorageService, DicomDecompressor, and others) require that the <b>[[Java Advanced Imaging ImageIO Tools]]</b> be present on the system. If you already have the ImageIO Tools installed, note that it is critically important that version 1.1 of the ImageIO Tools be installed rather than version 1.0. Parenthetically, note that the Java Advanced Imaging component is not the same as the Java Advanced Imaging ImageIO Tools. Only the latter component is required. (Macintosh users should read [[#ImageIO_Tools_for_Macintosh|ImageIO Tools for Macintosh]] in the Notes section.) When the CTP installer runs, it checks several parameters of the system and highlights ones that are not correct for the running of CTP. One such parameter is the version of the ImageIO Tools. The ImageIO Tools need not be present in order to run the installer, and they may be installed later if required, without having to re-install CTP. <br />
<br />
Note also that the CTP installer includes the ImageIO Tools for Windows 32-bit Java only, so on such systems, you can skip the installation of the ImageIO Tools, but that will make the tools only available for CTP, not for other applications. If you are planning to install certain other RSNA DICOM tools (for example, DicomEditor), it is best to install the ImageIO Tools directly in Java using the installer provided in [[Java Advanced Imaging ImageIO Tools]].<br />
<br />
To run the CTP installer, double-click the <tt><b>CTP-installer.jar</b></tt> file and choose a directory in which to install CTP. The installer can also be run in a command window using the command:<br />
<br />
:<b><tt>java -jar CTP-installer.jar</tt></b><br />
<br />
The installer creates a directory called <b>CTP</b> in the selected location and places several files and directories in it. Two files of special importance are:<br />
<br />
* <b>Launcher.jar</b> - the program that launches CTP with a user interface<br />
* <b>Runner.jar</b> - the program that starts or stops CTP with no user interface<br />
<br />
===Running CTP===<br />
There are three ways to start CTP:<br />
* <b><tt>Launcher.jar</tt></b> - a program for manually starting and stopping CTP through a dialog window. This program is normally used when CTP is installed on an individual user's computer for occasional use.<br />
* <b><tt>Runner.jar</tt></b> - a program for starting and stopping CTP with no user interface. This program is normally used when CTP is installed on a Linux or Mac system for institutional use, running as an automatic service. See [[Running CTP as a Linux Service]] for instructions.<br />
* CTP can also be run as a Windows service. See [[Running CTP as a Windows Service]] for instructions. <br />
<br />
The launcher displays a dialog providing start/stop buttons and fields for controlling several parameters used by the system.<br />
<br />
The <b>Server port</b> field allows you to change the port on which the server runs.<br />
<br />
The default memory configuration is sufficient for all but the very largest sites. For sites with 2000 or more teaching file cases, the <b>Maximum memory pool</b> parameter should be increased to 500. For sites with more than 3000 cases, 750 is recommended. To change the memory configuration for the Windows service, see the article.<br />
<br />
The <b>Extensions directory</b> parameter is intended for special applications in which third-party software is added into the system. One such application is the NCI's National Biomedical Image Archive (NBIA). Normal teaching file systems do not require this parameter.<br />
<br />
Across the top of the dialog are several tabs providing access to information about the versions of the components, the system parameters in use by Java as the program runs, and any messages output by the program either directly or through its log file. These are only present as a convenience; they are not typically used in normal operation.<br />
<br />
As a convenience, the <b>CTP Home Page</b> button launches the user's browser and goes directly to the main MIRC page.<br />
<br />
CTP has no user interface. When the program starts, it runs without intervention. Status and other information can be obtained through the program's integrated webserver. Accessing the server with no path information displays a page presenting buttons for each of the servlets. <br />
<br />
When the program is first installed, two users are provided. One user, with the name <b>admin</b> and password <b>password</b>, is intended for general system administration. The other user, with the name <b>king</b> and password <b>password</b>, has the ability to shut down the server through the browser interface. Both users have the ability to create and modify users and assign privileges through the User Manager, but only a user with the shutdown privilege can grant the shutdown privilege to another user.<br />
<br />
To stop the program, click the <b>Stop</b> button on the Launcher, or log in as a user with the shutdown privilege and click the <b>Shutdown</b> button on the main page. As a convenience, a user with the admin privilege can also shut the server down if the user's browser is running on the same computer as the server.<br />
<br />
===Configuration Files===<br />
The program uses two configurable files: <b><tt>config.xml</tt></b>, which is located in the same directory as the program itself, and <b><tt>index.html</tt></b>, which is located in the server's <b><tt>ROOT</tt></b> directory. Both files are intended to be configured for the specific application. The installer does not overwrite these files when it runs; instead, it installs two example files: <b><tt>example-config.xml</tt></b> and <b><tt>example-index.html</tt></b>. When CTP starts, it looks to see if the non-example files are missing, and if so, it copies the example files into the non-example ones. This process allows upgrades to be done without losing any configuration work. After installing the program the first time, it should be run once in order to make the copies, and then the copies can be configured. Configuration is done by hand with any text editor (e.g., TextPad or NotePad). Care should be taken, especially with config.xml, to keep it well-formed. Opening it with a program like InternetExplorer will check it for errors.<br />
<br />
===Server===<br />
To provide access to the status of the components, the application includes an HTTP server which serves files and provides servlet-like functionality. Files are served from a directory tree whose root is named <b><tt>ROOT</tt></b>. The <b><tt>ROOT</tt></b> directory contains a file, <b><tt>index.html</tt></b>, which provides buttons which link to several servlets providing information about the operation of the program. This file is intended to be configured with logos, additional links, etc., and upgrades do not overwrite it. The standard servlets are:<br />
<br />
*<b>LoginServlet</b> allows a user to log into the system.<br />
*<b>UserManagerServlet</b> allows an admin user to create users and assign them privileges.<br />
*<b>ConfigurationServlet</b> displays the contents of the configuration file.<br />
*<b>SysPropsServlet</b> displays the system properties which define the environment in which CTP is running, and provides an admin user the ability to force a garbage collection.<br />
*<b>StatusServlet</b> displays the status of all pipeline stages.<br />
*<b>LogServlet</b> provides web access to all log files in the <b>logs</b> directory.<br />
*<b>QuarantineServlet</b> provides web access to all quarantine directories and their contents.<br />
*<b>IDMapServlet</b> allows an admin user to access a database of PHI and anonymized replacements for patient IDs accession numbers, and UIDs.<br />
*<b>ObjectTrackerServlet</b> allows an admin user to access a database of the identifiers of objects which have been processed, organized by date, patient ID, Study UID, Series UID, and Instance UID.<br />
*<b>DBVerifierServlet</b> allows an admin user to access a database which tracks the status of objects as they are inserted into an external database (which may be in a remote instance of CTP).<br />
*<b>DicomAnonymizerServlet</b> allows an admin user to configure any DICOM anonymizers in the pipelines.<br />
*<b>ScriptServlet</b> allows an admin user to configure the scripts for script-based pipeline stages, including the various Filter stages and the XML and Zip anonymizers.<br />
*<b>LookupServlet</b> allows an admin user to configure lookup tables used by the anonymizers.<br />
*<b>ShutdownServlet</b> allows an admin user to shut the program down.<br />
<br />
The configuration element for the HTTP server is:<br />
<pre><br />
<Server <br />
port="80"<br />
ssl="no"<br />
requireAuthentication="no"<br />
usersClassName="org.rsna.server.UsersXmlFileImpl"><br />
<ProxyServer<br />
proxyIPAddress=""<br />
proxyPort=""<br />
proxyUsername=""<br />
proxyPassword=""/><br />
<SSL<br />
keystore=""<br />
keystorePassword=""<br />
truststore=""<br />
truststorePassword=""/><br />
</Server><br />
<br />
</pre><br />
where:<br />
*<b>port</b> is the port number on which the HTTP server listens for connections.<br />
*<b>ssl</b> determines whether the HTTP server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the HTTP server. Values are "yes" and "no". The default is "no". (The HTTP server is typically operated without requiring authentication, thus allowing users to monitor the status of the system without having to log in.)<br />
*<b>proxyIPAddress</b> is the IP address of the proxy server. If this attribute is missing or blank, no proxy server is used. If a proxy server is configured, it is shared by all pipeline stages and servlets.<br />
*<b>proxyPort</b> is the port of the proxy server. If this attribute is missing or blank, no proxy server is used.<br />
*<b>proxyUsername</b> is the username which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>proxyPassword</b> is the password which is to be supplied to the proxy server if proxy authentication is required. If this attribute is missing or blank, no credentials will be supplied to the proxy server.<br />
*<b>keystore</b> specifies the path to the keystore file. If this attribute is missing or blank, the value <b><tt>keystore</tt></b> is supplied.<br />
*<b>keystorePassword</b> is the password for access to the keystore. It this attribute is missing or blank, the value <b><tt>ctpstore</tt></b> is used.<br />
*<b>truststore</b> specifies the path to the truststore file. If this attribute is missing or blank, the corresponding property is removed from the system properties.<br />
*<b>truststorePassword</b> is the password for access to the truststore.<br />
*<b>usersClassName</b> specifies the Java class to be used for authentication of users and their privileges. If this attribute is missing, the standard CTP implementation (shown above) is employed. This attribute should only be included if a special mechanism has been implemented on the site (for example, using LDAP or OpenAM - see [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]]).<br />
<br />
Notes:<br />
*The ProxyServer element is only required when the system is behind a proxy server.<br />
*The SSL element is only required when accessing a site-specific keystore or truststore instead of the default stores supplied in a CTP installation.<br />
*When an external authentication system is used for authentication, the Server element may have a child element containing its parameters. Examples are the LDAP and OpenAM child elements. See [[CTP Authentication Using LDAP]] or [[CTP Authentication Using OpenAM]].<br />
<br />
===Plugins===<br />
A plugin is a component that adds functionality to CTP outside the context of a pipeline. Plugins can add servlets to the server as well as provide capabilities that may be accessed by pipeline stages.<br />
<br />
===Pipelines===<br />
A pipeline is a manager that moves data objects through a sequence of processing stages. Each stage in the pipeline performs a specific function on one or more of the four basic object types supported by MIRC:<br />
:*FileObject<br />
:*DicomObject<br />
:*XmlObject<br />
:*ZipObject<br />
Each pipeline must contain at least one ImportService. Each pipeline stage may be provided access to a quarantine directory into which the stage places objects that it rejects, thus removing them from the pipeline and aborting further processing. Quarantine directories may be unique to each stage or shared with other stages. At the end of the pipeline, the manager calls the ImportService which provided the object to remove it from its queue. <br />
<br />
There are four types of pipeline stages. Each is briefly described in subsections below.<br />
<br />
====ImportService====<br />
An ImportService receives objects via a protocol and enqueues them for processing by subsequent stages.<br />
<br />
====Processor====<br />
A Processor performs some kind of processing on an object. Processors are not intended to be queued. In the context of the current MIRC implementation, a Preprocessor is a Processor, as is an Anonymizer. The result of a processing stage is an object that is passed to the next stage in the pipeline.<br />
<br />
====StorageService====<br />
A StorageService stores an object in a file system. It is not queued, and it therefore must complete before subsequent stages can proceed. A StorageService may return the current object or the stored object in response to a request for the output object, depending on its implementation.<br />
<br />
====ExportService====<br />
An ExportService provides queued transmission to an external system via a defined protocol. Objects in the queue are full copies of the objects submitted; therefore, subsequent processing is not impeded if a queue is paused, and modifications made subsequently do not affect the queue entry, even if they occur before transmission. (Note: This behavior is different from that of the current MIRC implementation.) After entering an object in its queue, an ExportService returns immediately.<br />
<br />
===System Configuration===<br />
The CTP configuration is specified by an XML file called <tt><b>config.xml</b></tt> located in the same directory as the program. There can be one <b>Server</b> element specifying the port on which the HTTP server is to operate, and multiple <b>Pipeline</b> elements, each specifying the stages which comprise it. The name of the element defining a stage is irrelevant and can be chosen for readability; each stage in a pipeline is actually defined by its Java class, specified in the <b>class</b> attribute. Stages are loaded automatically when the program starts, and the loader tests the stage's class to determine what kind of stage it represents. It is possible to extend the application beyond the pre-defined stages available in the implementation as described in [[Extending CTP]].<br />
<br />
The following is an example of a simple configuration that might be used at an image acquisition site. It contains one pipeline which receives objects via the DICOM protocol, stores the objects locally, anonymizes them, and transmits them via HTTP (using secure sockets layer for encryption) to a principal investigator's site.<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<DicomImportService<br />
name="DicomImportService"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="roots/dicom-import"<br />
port="1104" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="storage"<br />
returnStoredFile="no"<br />
quarantine="quarantines/storage" /><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="roots/anonymizer"<br />
script="scripts/da.script"<br />
quarantine="quarantines/anonymizer" /><br />
<HttpExportService<br />
name="HttpExportService"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="roots/http-export"<br />
url="https://university.edu:1443" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
<br />
Note that because the storage service appears in the pipeline before the anonymizer, the objects which are stored contain the PHI which was originally received, and because the anonymizer appears before the export service, anonymized objects are exported.<br />
<br />
The following is an example of a simple configuration that might be used at a principal investigator's site. It contains one pipeline which receives objects via the HTTP protocol, stores them, and exports them to a DICOM destination:<br />
<pre><br />
<Configuration><br />
<Server port="80" /><br />
<Pipeline name="Main Pipeline"><br />
<HttpImportService<br />
name="HttpImportService"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="roots/http-import"<br />
ssl="yes"<br />
port="1443" /><br />
<FileStorageService<br />
name="FileStorageService"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/FileStorageService" <br />
returnStoredFile="no"<br />
quarantine="quarantines/StorageServiceQuarantine" /><br />
<DicomExportService<br />
name="DicomExportService"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="roots/pacs-export" <br />
url="dicom://DestinationAET:ThisAET@ipaddress:port" /><br />
</Pipeline><br />
</Configuration><br />
</pre><br />
Note that in the example above, non-DICOM objects are stored in the StorageService, but they are not exported by the DicomExportService. Each pipeline stage is responsible for testing the class of the object which it receives and processing (or ignoring) the object accordingly.<br />
<br />
Multiple <b>Pipeline</b> elements may be included, but each must have its own ImportService element, and their ports must not conflict.<br />
<br />
Each pipeline stage class has a constructor that is called with its configuration element, making it possible for special processor implementations to be passed additional parameters from the configuration.<br />
<br />
===Standard Plugins===<br />
The application includes built-in, standard plugins to provide features that are required in some clinical trials. The sections below show all the configuration attributes recognized by the standard plugins. Note that the configuration element for a plugin always has the tag name <b><tt>Plugin</tt></b>.<br />
<br />
=====AuditLog=====<br />
The AuditLog plugin provides a permanent log repository to meet the logging requirements of a 21CFR11-compliant clinical trial. Certain pipeline stages can be configured to make entries in the log repository.<br />
<br />
The AuditLog plugin installs a servlet to provide browser access to the repository for admin users. The servlet is accessed with a path equal to the value of the AuditLog plugin's <b><tt>id</tt></b> attribute. It is possible to configure multiple AuditLog Plugin elements (with different <b><tt>id</tt></b> attributes) if multiple trials are serviced by a single CTP instance and it is desired to keep the log repositories separate. The configuration element for the AuditLog is:<br />
<pre><br />
<Plugin<br />
name="log name"<br />
id="pluginID"<br />
class="org.rsna.ctp.stdplugins.AuditLog"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is text to be used to uniquely identify the plugin. Note that since the value of the attribute is used as the context of the servlet that provides access to the repository, it must be a single word (that is, it must not contain whitespace).<br />
*<b>root</b> is a directory for use by the plugin for internal storage of the database.<br />
<br />
=====Redirector=====<br />
The Redirector plugin redirects non-secure HTTP connections to another port using SSL. It is intended for use on CTP installations that configure the main server to use SSL. Such installations typically put the server on port 443. As a convenience for users, the Redirector can be configured to listen on port 80 and redirect the user to port 443, switching the protocol.<br />
<br />
The configuration element for the Redirector is:<br />
<pre><br />
<Plugin<br />
name="Redirector"<br />
class="org.rsna.ctp.stdplugins.Redirector"<br />
httpPort="80"<br />
httpsHost="mirc.mysecuresite.myuniversity.edu"<br />
httpsPort="443" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>httpPort</b> is the port on which the Redirector listens for connections.<br />
*<b>httpsHost</b> is the host to which the Redirector redirects the connection request.<br />
*<b>httpsPort</b> is the port to which the Redirector redirects the connection request.<br />
<br />
Notes:<br />
* The redirection only occurs on HTTP GET requests. <br />
* If the <b>httpsHost</b> attribute is missing or empty, the value of the HOST header is used in the target URL.<br />
* The query string, if any, is included in the target URL.<br />
<br />
===Standard Stages===<br />
The application includes several built-in, standard stages which allow most trials to be operated without writing any software. The sections below show all the configuration attributes recognized by the standard stages. <br />
<br />
Attributes which specify directories can contain either absolute paths (e.g., <tt><b>D:/TrialStorage</b></tt>) or relative paths (e.g., <tt><b>quarantines/http-import-quarantine</b></tt>). Relative paths are relative to the directory in which the CTP application is located.<br />
<br />
All standard stages have a <b>root</b> attribute which defines a directory for use by the stage for internal storage. All <b>root</b> directories must be unique, e.g. not shared with other stages.<br />
<br />
All standard stages have an optional <b>id</b> attribute which, if present, must uniquely identify the stage across all pipelines. This attribute is required only when the stage must be accessed by another stage, for example, when a DatabaseExportService must interrogate a FileStorageService to determine the URL under which an object is stored.<br />
<br />
Some standard stages have attributes which determine which object types are to be accepted by the stage. These attributes are:<br />
*acceptDicomObjects<br />
*acceptXmlObjects<br />
*acceptZipObjects<br />
*acceptFileObjects<br />
The allowed values are <b>yes</b> and <b>no</b>. The default value for all these attributes is <b>yes</b>. Stages which are restricted to specific object types (e.g. DicomImportService, DicomAnonymizer, XmlAnonymizer, DicomFilter, DicomExportService) ignore the values of these attributes.<br />
<br />
If a standard ImportService receives an object which it is not configured to accept, it quarantines the object, or if no quarantine has been defined for the stage, it discards the object.<br />
<br />
If a Processor, StorageService, or ExportService receives an object that it is not configured to accept, it either ignores the object or passes it unmodified to the next pipeline stage. Thus, if an anonymizer which is not configured to anonymize XmlObjects receives an XmlObject, it passes the object on without anonymization.<br />
<br />
====Import Services====<br />
=====HttpImportService=====<br />
The HttpImportService listens on a defined port for connections from HTTP clients and receives files transmitted using the HTTP protocol with Content-Type equal to <b><tt>application/x-mirc</tt></b>. The configuration element for the HttpImportService is:<br />
<pre><br />
<HttpImportService<br />
name="HttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
zip="no"<br />
requireAuthentication="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with zipped transmissions from the HttpExportService.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====PollingHttpImportService=====<br />
The PollingHttpImportService obtains files by initiating HTTP connections to an external system. This ImportService is designed to work in conjunction with the PolledHttpExportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the PollingHttpImportService is:<br />
<pre><br />
<PollingHttpImportService<br />
name="PollingHttpImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PollingHttpImportService"<br />
root="root-directory"<br />
url="http://ip:port"<br />
zip="no"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage.<br />
*<b>url</b> is the URL of the PolledHttpExportService.<br />
*<b>zip</b> determines whether files will be unzipped after reception (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be enqueued when received.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be enqueued when received.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be enqueued when received.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be enqueued when received.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
Notes: <br />
*The protocol part of the <b>url</b> must be <b>http</b>, although the actual protocol used by the PollingHttpImportService is not HTTP.<br />
*The PollingHttpImportService does not support SSL.<br />
*The PollingHttpImportService does not support a proxy server for its connections.<br />
<br />
=====DicomImportService=====<br />
The DicomImportService listens on a defined port for connections from DICOM Storage SCUs and receives files transmitted using the DICOM protocol. The DicomImportService accepts all Application Entity Titles. The configuration element for the DicomImportService is:<br />
<pre><br />
<DicomImportService<br />
name="DicomImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomImportService"<br />
root="root-directory" <br />
port="port number" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
connectionIPTag="00097774"<br />
timeTag="00097776"<br />
throttle="0"<br />
logConnections="no"<br />
logDuplicates="no"<br />
suppressDuplicates="no" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
<accept calledAET="..."/><br />
<reject calledAET="..."/><br />
<br />
<accept callingAET="..."/><br />
<reject callingAET="..."/><br />
<br />
<accept sopClass="..."/><br />
<br />
</DicomImportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to specify the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the receiver in the received DICOM object.<br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the AE Title which was used by the sender to identify itself in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the AE Title of the sender in the received DICOM object.<br />
*<b>connectionIPTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the IP address of the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the IP address of the sender in the received DICOM object.<br />
*<b>timeTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, into which to store the system time when the object is received. If the attribute is missing or zero, or if the value does not parse as a hex integer, the DicomImportService does not store the system time in the received DICOM object. (The system time is the time in milliseconds since January 1, 1970.)<br />
*<b>throttle</b> sets the time delay (in milliseconds) before sending a response to the SCP on each transmission. The default is 0 milliseconds.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes the SOPInstanceUID, the IP address of the sender in the association, and the calledAET and CallingAET. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose SOPInstanceUID matches that of any other object in the last 20 that have been received. This capability is intended primarily for configuration debugging. <br />
*<b>suppressDuplicates</b> specifies whether to ignore objects which have the same SOPInstanceUID as any object in the last 10 objects received. Values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. This capability is intended primarily for configuration debugging.<br />
*The <b>accept</b> child elements can be used to specify white lists of values determining which connections are to be accepted. One <b>accept</b> child element must appear for each value in the white list. If the white list is empty, the white list is not used to filter connections. There are four white lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), SCP application entity titles (calledAET), and SOP Classes (sopClass). (Note: SOP Classes can be specified as either the UID value or the dcm4che name. For example, both "1.2.840.10008.5.1.4.1.1.4" and "MRImageStorage" are accepted. Care should be taken when specifying SOP Class names, as unknown names are ignored.)<br />
*The <b>reject</b> child elements can be used to specify black lists of values determining which connections are to be rejected. One <b>reject</b> child element must appear for each value in the black list. If the black list is empty, the black list is not used to filter connections. There are three black lists, one each for client IP addresses (ip), SCU application entity titles (callingAET), and SCP application entity titles (calledAET).<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
=====DicomSTOWRSImportService=====<br />
The DicomSTOWRSImportService listens on a defined port for HTTP or HTTPS connections from clients and receives files transmitted using the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSImportService is:<br />
<pre><br />
<HttpImportService<br />
name="DicomSTOWRSImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSImportService"<br />
root="root-directory"<br />
port="7777"<br />
ssl="yes"<br />
requireAuthentication="no"<br />
logConnections="no"<br />
logDuplicates="no"<br />
quarantine="quarantine-directory" ><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</HttpImportService> <br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ImportService listens for connections.<br />
*<b>ssl</b> determines whether the port uses secure sockets layer (<b>yes</b>) or unencrypted http (<b>no</b>). The default is <b>no</b>.<br />
*<b>requireAuthentication</b> determines whether transmissions are required to have headers which identify a user which has the <b>import</b> privilege. The allowed values are <b>yes</b>) and <b>no</b>. The default is <b>no</b>.<br />
*<b>logConnections</b> specifies whether to make a log entry for each object that is received. The log entry includes only the IP address of the sender. The values <b>yes</b> and <b>all</b> cause all connections to be logged. The value <b>rejected</b> causes only rejected connections to be logged. The default is <b>no</b>, meaning that no connections are logged. This capability is intended primarily for configuration debugging.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it receives but is configured not to accept.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
*The <b>accept</b> and <b>reject</b> child elements support the <b>regex</b> attribute in place of the <b>ip</b> attribute, allowing a range of IP addresses to be matched. The <b>regex</b> attribute must contain a regular expression. For example, to match any IP address in the <tt>10.10.*.*</tt> range, the <b>accept</b> element would be coded:<br />
<br />
<pre><br />
<accept regex="10\.10\.[0-9]{1,3}\.[0-9]{1,3}"/><br />
</pre><br />
<br />
=====DirectoryImportService=====<br />
The DirectoryImportService watches a directory and imports any files it finds in it. After the files are passed down the pipeline, they are deleted from the import directory. The purpose of this ImportService is to allow manual input of objects to the pipeline. The configuration element for the DirectoryImportService is:<br />
<pre><br />
<DirectoryImportService<br />
name="DirectoryImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DirectoryImportService"<br />
root="root-directory"<br />
import="import-directory"<br />
interval="20000"<br />
fsName="..."<br />
fsNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>import</b> is the directory monitored by the ImportService for files to import.<br />
*<b>interval</b> is the length of time in milliseconds between polls of the import directory. The default is 20000. If the value is less than 1000, a value of used.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows a DirectoryImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem. <br />
<br />
Note: When inserting the fsName value into the fsNameTag element in the DicomObject, there is a special feature. If the value of the fsName attribute is <b>@filename</b>, then the name of the file is inserted into the target element. If the filename ends in ".dcm", that string is removed from the end of the name before the name is inserted into the fsNameTag element.<br />
<br />
=====ArchiveImportService=====<br />
The ArchiveImportService walks the directory tree of a static archive and imports the files it finds. The files are copied from the archive and placed in a separate directory before being passed down the pipeline. When the files have been processed, they are deleted from the directory to which they were copied, but they remain in the archive. The purpose of this ImportService is to allow a complete archive to be processed. The ImportService checkpoints itself as it runs, and restarts where it left off if the program is stopped and restarted. The checkpoint is stored in a file called <b><tt>checkpoint.bin</tt></b> in the stage's root directory. To restart the stage from the tree root, the checkpoint file must be deleted and CTP must be restarted.<br />
<br />
The configuration element for the ArchiveImportService is:<br />
<pre><br />
<ArchiveImportService<br />
name="ArchiveImportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ArchiveImportService"<br />
root="root-directory"<br />
treeRoot="archive-root-directory"<br />
expandTARs="no"<br />
minAge="5000"<br />
fsName="..."<br />
fsNameTag=""<br />
filePathTag=""<br />
fileNameTag=""<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ImportService to manage imported files.<br />
*<b>treeRoot</b> is the root directory of the archive.<br />
*<b>expandTARs</b> determines whether the ImportService is to expand any TAR files it finds in the archive as they are imported. For archives containing TAR files encapsulating DICOM images, this attribute should be set to <b>yes</b>; otherwise, the TAR files will be treated as FileObjects containing no identifiers which would allow them to be connected to other objects.<br />
*<b>minAge</b> is the minimum age (in milliseconds) for files which are imported from the root directory. The default value is <b>5000</b>; the minimum accepted value is <b>1000</b>. The purpose of this attribute is to ensure that files are completely stored in the root directory before being imported.<br />
*<b>fsName</b> is the name of the FileSystem to be used by a FileStorageService that receives this object.<br />
*<b>fsNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the value of the fsName attribute.<br />
*<b>filePathTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the path at which the file was found in the archive. The path starts with the name of the treeRoot directory and ends at the name of the directory that contained the file. It does not include the name of the file. The '/' path separator character is used on all platforms.<br />
*<b>fileNameTag</b> is the name of a DICOM element, specified in hex with no comma separating the group and element numbers, in which to store the name of the file that was found in the archive.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be accepted.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be accepted.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be accepted.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be accepted.<br />
*<b>quarantine</b> is a directory in which the ImportService is to quarantine objects that it has handled (whether they were accepted for importing or not).<br />
<br />
Note: For DicomObjects, if both the <b>fsName</b> and <b>fsNameTag</b> attributes are specified, the stage places the value of the fsName attribute in the element identified by fsNameTag. This allows an ArchiveImportService to mimic the behavior of a DicomImportService which stores the Called AE Title or Calling AE Title in an element for later use by a FileStorageService to assign the object to a FileSystem.<br />
<br />
====Processors====<br />
=====ObjectLogger=====<br />
The ObjectLogger is a processor stage that logs the passage of objects as they flow past. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the ObjectLogger is:<br />
<pre><br />
<ObjectLogger<br />
name="ObjectLogger"<br />
class="org.rsna.ctp.stdstages.ObjectLogger"<br />
interval="1"<br />
verbose="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
*<b>verbose</b> increases the amount of information logged.<br />
<br />
=====ObjectCache=====<br />
The ObjectCache is a processor stage that caches the current object as it flows past. Objects are passed on unmodified. The cached object is saved as a separate file to capture the object before it is changed by downstream processors. This stage is intended for use in conjunction with an audit stage that logs changes to objects or for special uses of the DirectoryExportService stage in the RSNA Image Sharing project. To make the cached object available to subsequent stages, the <b>id</b> attribute is mandatory. The configuration element for the ObjectCache is:<br />
<pre><br />
<ObjectCache<br />
name="ObjectCache"<br />
class="org.rsna.ctp.stdstages.ObjectCache"<br />
id="stage ID"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ObjectCache for temporary storage.<br />
<br />
=====DicomAuditLogger=====<br />
The DicomAuditLogger is a processor stage that makes entries in an AuditLog plugin for DicomObjects. Objects are passed on unmodified. The AuditLog entries contain the values of specified elements in the DicomObject and optionally the corresponding elements in a DicomObject contained in the specified ObjectCache stage. The configuration element for the DicomAuditLogger is:<br />
<pre><br />
<DicomAuditLogger<br />
name="DicomAuditLogger"<br />
class="org.rsna.ctp.stdstages.DicomAuditLogger"<br />
root="roots/DicomAuditLogger"<br />
auditLogID="AuditLog"<br />
auditLogTags="PatientID;PatientName;SOPInstanceUID"<br />
cacheID="ObjectCache"<br />
level="instance" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomAuditLogger for temporary storage.<br />
*<b>auditLogID</b> is the ID of an AuditLog plugin in which entries are to be made.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
*<b>level</b> specifies granularity of the log. Three levels are supported:<br />
:* <b><tt>patient</tt></b>: one entry for each unique PatientID processed by the stage<br />
:* <b><tt>study</tt></b>: one entry for each unique StudyInstanceUID processed by the stage<br />
:* <b><tt>instance</tt></b>: one entry for each unique SOPInstanceUID processed by the stage<br />
<br />
Notes:<br />
# If the cacheID attribute is not specified, or if it does not point to an ObjectCache stage, the AuditLog entries contain only the values of the DicomObject being processed.<br />
# If the cacheID attribute points to an ObjectCache stage, and that stage can supply a DicomObject, the AuditLog entry contains the values of both the DicomObject being processed and the cached object.<br />
# By caching an object before anonymization and putting a DicomAuditLogger after the anonymizer, you can create AuditLog entries with the PHI and anonymized values. (Note that the AuditLog is visible only to an admin user.)<br />
<br />
=====MemoryMonitor=====<br />
The MemoryMonitor is a processor stage that provides a way to force garbage collection and/or to log the current memory in use by CTP. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial; it creates one entry in the system log for each object it receives (unless the <b>interval</b> attribute is supplied with a value greater than one). Logging every object in a large production system can produce an unwieldy log file. The configuration element for the MemoryMonitor is:<br />
<pre><br />
<MemoryMonitor<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.MemoryMonitor"<br />
interval="1"<br />
collectGarbage="yes"<br />
logMemoryInUse="yes" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>.<br />
*<b>collectGarbage</b> determines whether the stage is to force the garbage collector to run. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
*<b>logMemoryInUse</b> determines whether the stage is to log the current amount of heap space in use. If garbage collection is enabled, the value logged is the memory in use after garbage collection is complete. The allowed values are <b>yes</b> and <b>no</b>. The default is <b>yes</b>.<br />
<br />
=====PerformanceLogger=====<br />
The PerformanceLogger is a processor stage that logs the elapsed time taken by each stage in the pipeline during the processing of the current object. Objects are passed on unmodified. The log entries are made in the system log and can be viewed in the log viewer servlet on the main admin server page. This stage is intended for initial configuration testing for a new trial. The configuration element for the PerformanceLogger is:<br />
<pre><br />
<PerformanceLogger<br />
name="stage name"<br />
class="org.rsna.ctp.stdstages.PerformanceLogger"<br />
interval="1" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>interval</b> is the interval between objects to log. The default is <b>1</b>. This attribute can be used to measure performance without imposing a large load on the log file by setting the value to, for example, <b>1000</b>.<br />
<br />
=====DicomFilter=====<br />
The DicomFilter is a processor stage that interrogates a DicomObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a DicomObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (XmlObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the DicomFilter is:<br />
<pre><br />
<DicomFilter<br />
name="DicomFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomFilter"<br />
root="root-directory" <br />
script="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the DicomFilter.<br />
*<b>quarantine</b> is a directory in which the DicomFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP DICOM Filter]].<br />
<br />
=====XmlFilter=====<br />
The XmlFilter is a processor stage that interrogates an XmlObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If an XmlObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, ZipObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<XmlFilter<br />
name="XmlFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlFilter"<br />
root="root-directory" <br />
script="scripts/xml-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the XmlFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the XmlFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====ZipFilter=====<br />
The ZipFilter is a processor stage that interrogates the manifest of a ZipObject to determine whether it meets criteria specified in a script file. If a script file is either not configured or absent, objects are passed on unmodified. If a ZipObject meets the specified criteria, it is passed on unmodified. If it does not meet the criteria, it is quarantined. If no quarantine is specified, the object is deleted. Objects of any other type (DicomObject, XmlObject, FileObject) are passed on unmodified. The configuration element for the XmlFilter is:<br />
<pre><br />
<ZipFilter<br />
name="ZipFilter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipFilter"<br />
root="root-directory" <br />
script="scripts/zip-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ZipFilter for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlFilter.<br />
*<b>quarantine</b> is a directory in which the ZipFilter is to quarantine objects that do not meet the criteria specified in the script file.<br />
<br />
For information on specifying acceptance criteria in the script, see [[The CTP XML and Zip Filters]].<br />
<br />
=====IDMap=====<br />
The IDMap is a processor stage that constructs map tables for UID elements, AccessionNumber elements, and PatientID elements. The map tables contain the original values and the replacement values created by the first downstream anonymizer. These tables can be accessed by administrators using the IDMap servlet. The configuration element for the IDMap is:<br />
<pre><br />
<IDMap<br />
name="IDMap"<br />
class="org.rsna.ctp.stdstages.IDMap"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDMap for permanent storage of the map tables.<br />
<br />
=====ObjectTracker=====<br />
The ObjectTracker is a processor stage that tracks objects by date, PatientID, StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID. The values tracked are the ones in the objects at the time they arrive at the stage, so if they occur before anonymization, they contain PHI. The tracking tables can be accessed by administrators using the ObjectTracker servlet. The configuration element for the IDTracker is:<br />
<pre><br />
<ObjectTracker<br />
name="ObjectTracker"<br />
class="org.rsna.ctp.stdstages.ObjectTracker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the IDTracker for permanent storage of its tracking tables.<br />
<br />
=====DatabaseVerifier=====<br />
The DatabaseVerifier is a processor stage that tracks objects which have been passed to an external database. The stage periodically polls the DatabaseExportService of the external database and maintains its own internal database indicating the status of the objects. The DBVerifierServlet provides a browser interface to the internal database. There can be no anonymizer stages (either DicomAnonymizers or DicomPixelAnonymizers) between the DatabaseVerifier and the DatabaseExportService. (The reason is that the DatabaseVerifier indexes objects by SOPInstanceUID, and it determines that the object in the remote database matches the one seen earlier by the DatabaseVerifier stage by comparing the hashes of the objects' binary contents.) The configuration element for the DatabaseVerifier is:<br />
<pre><br />
<DatabaseVerifier<br />
name="DatabaseVerifier"<br />
class="org.rsna.ctp.stdstages.DatabaseVerifier"<br />
root="root-directory"<br />
url="http:ip:port"<br />
username=""<br />
password=""<br />
interval="10000"<br />
maxAge="0" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DatabaseVerifier for permanent storage of its internal database.<br />
*<b>url</b> specifies the URL of the verification service of the external database's DatabaseExportService. If <b>ssl</b> is enabled on that verification service, the <b>url</b> attribute must start with <tt><b>https://</b></tt>. If this attribute is missing, no verication is performed, although the internal database is still maintained.<br />
*<b>username</b> specifies the username credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>password</b> specifies the password credential for inclusion in verification requests. If this attribute is missing or blank, credentials are not supplied in verification requests.<br />
*<b>interval</b> specifies time in milliseconds between queries of the external database's DatabaseExportService. If this attribute is missing or blank, the interval is 10 seconds (10,000 msec).<br />
*<b>maxAge</b> specifies the maximum time in days that an unverified object is allowed to remain in the unverified queue before the DatabaseVerifier removes it and stops trying to verify it with the external database's DatabaseExportService. If the attribute is missing or zero, objects remain in the queue forever until they are verified.<br />
<br />
=====DicomDecompressor=====<br />
The DicomDecompressor is a processor stage that converts DicomObjects containing encapsulated pixel data into DicomObjects with the Explicit VR Little Endian (EVRLE) transfer syntax. It passes all other object types unmodified. The DicomDecompressor can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomDecompressor<br />
name="DicomDecompressor"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomDecompressor"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-decompressor.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomDecompressor for temporary storage.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for decompression.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
Notes:<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====DicomPlanarConfigurationConverter=====<br />
The DicomPlanarConfigurationConverter is a processor stage that converts DicomObjects from PlanarConfiguration 1 to PlanarConfiguration 0. It passes all other object types unmodified. The configuration element for the DicomPlanarConfigurationConverter is:<br />
<pre><br />
<DicomPlanarConfigurationConverter <br />
name="DicomPlanarConfigurationConverter "<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPlanarConfigurationConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPlanarConfigurationConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomPaletteImageConverter=====<br />
The DicomPaletteImageConverter is a processor stage that converts DicomObjects from PhotometricInterpretation PALETTE COLOR to RGB. It passes all other object types unmodified. The configuration element for the DicomPaletteImageConverter is:<br />
<pre><br />
<DicomPaletteImageConverter <br />
name="DicomPaletteImageConverter"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPaletteImageConverter"<br />
root="root-directory" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPaletteImageConverter for temporary storage.<br />
*<b>quarantine</b> is a directory in which the stage is to quarantine objects.<br />
<br />
=====DicomTranscoder=====<br />
The DicomTranscoder is a processor stage that converts DicomObjects to a specified transfer syntax. It passes all other object types unmodified. The DicomTranscoder can optionally be configured with a script file which is used like a DicomFilter to select objects for processing. If a script file is either not configured or absent, all objects are processed. <br />
<br />
An example of the use of this stage is a pipeline that decompresses multiframe ultrasound images, blanks regions of the frames containing PHI, and then recompresses the images to save space. Such a pipeline might have these stages in sequence:<br />
* DicomDecompressor<br />
* DicomPixelAnonymizer<br />
* DicomTranscoder<br />
<br />
The configuration element for the DicomTranscoder is:<br />
<pre><br />
<DicomTranscoder<br />
name="DicomTranscoder"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomTranscoder"<br />
tsuid="transfer syntax UID"<br />
quality="100"<br />
root="root-directory" <br />
skipJPEGBaseline="no"<br />
script="scripts/dicom-transcoder.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>tsuid</b> is the DICOM transfer syntax UID of the processed DicomObject. These transfer syntaxes have been tested successfully:<br />
:<b><tt>tsuid="1.2.840.10008.1.2.1"</tt></b> (ExplicitVRLittleEndian)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.70"</tt></b> (JPEGLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.80"</tt></b> (JPEGLSLossLess)<br />
:<b><tt>tsuid="1.2.840.10008.1.2.4.90"</tt></b> (JPEG2000LossLess)<br />
*<b>quality</b> is an integer from 1 to 100 to indicate the desired quality of the processed DicomObject. This attribute is ignored in the lossless transfer syntaxes.<br />
*<b>skipJPEGBaseline</b> specifies whether to skip objects that are encoded in JPEGBaseline transfer syntax. Allowed values are "yes" and "no". The default is "no".<br />
*<b>root</b> is a directory for use by the DicomTranscoder for temporary storage.<br />
*<b>script</b> specifies the path to a script which can be used to select objects for transcoding.<br />
*<b>quarantine</b> is a directory in which the is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If this stage is configured with the ExplicitVRLittleEndian transfer syntax, its function is similar to that of the DicomDecompressor stage. The difference is that although the output of the DicomDecompressor is EVRLE when it performs a conversion, it only converts DicomObjects that contain encapsulated pixel data, leaving all other objects unmodified, while the DicomTranscoder stage modifies all objects.<br />
# The <b>quality</b> attribute is not used in lossless compression transfer syntaxes.<br />
# The JPEGBaseline transfer syntax (<b><tt>tsuid="1.2.840.10008.1.2.4.50"</tt></b>) does not work correctly.<br />
# The skipJPEGBaseline attribute is just a convenience. Skipping JPEGBaseline objects can also be accomplished by including a script like the following:<br />
:::<tt>!TransferSyntaxUID.equals("1.2.840.10008.1.2.4.50")</tt><br />
<br />
=====LookupTableChecker=====<br />
The LookupTableChecker is a processor stage that checks all @lookup function calls in the first downstream DicomAnonymizer stage and quarantines any objects for which the function calls will fail. It adds a servlet with the same context as the <b><tt>id</tt></b> attribute, allowing an admin user to insert values into the lookup table. Once the lookup table has been updated, the quarantined objects can be re-queued and processed successfully. The configuration element for the LookupTableChecker is:<br />
<pre><br />
<LookupTableChecker<br />
name="LookupTableChecker"<br />
class="org.rsna.ctp.stdstages.LookupTableChecker"<br />
root="root-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the LookupTableChecker for permanent storage of the map tables.<br />
<br />
=====DicomAnonymizer=====<br />
The DicomAnonymizer is a processor stage that anonymizes DicomObjects and passes all other object types unmodified. The DicomAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomAnonymizer<br />
name="DicomAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomAnonymizer"<br />
root="root-directory" <br />
lookupTable="scripts/lookup-table.properties"<br />
script="scripts/dicom-anonymizer.script"<br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>lookupTable</b> specifies the path to the lookup table used by the DicomAnonymizer.<br />
*<b>script</b> specifies the path to the script for the DicomAnonymizer.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to anonymize the object.<br />
*<b>quarantine</b> is a directory in which the DicomAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
Notes:<br />
# If the <b>lookupTable</b> attribute is missing, the <b>lookup</b> anonymizer function will result in the object being quarantined.<br />
# The <b>script</b> attribute specifies the instructions for modifying the individual elements in a DicomObject. If this attribute is missing, DicomObjects are not modified.<br />
# The <b>dicomScript</b> attribute specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# If the <b>@integer</b> function is used in the DicomAnonymizer script, the starting point can be reset by deleting the <b><tt>integers.db</tt></b> and <b><tt>integers.lg</tt></b> files from the directory specified in the <b>root</b> attribute. This will cause new integers to be assigned starting at <b>1</b>. Deleting the files must be done while CTP is not running.<br />
<br />
=====DicomCorrector=====<br />
The DicomCorrector is a processor stage that tries to fix problems in certain elements in DicomObjects that may have been coded incorrectly. Specifically, it recursively walks the dataset tree (including SQ item datasets) and finds non-private elements with VR=UN. For such elements defined in the standard to have the VRs FD, FL, or CS, it replaces the elements with the correct VR and VM for the data contained in the element. The DicomCorrector passes non-DicomObjects without modification. The configuration element for the DicomCorrector is:<br />
<pre><br />
<DicomCorrector<br />
name="DicomCorrector"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomCorrector"<br />
root="root-directory" <br />
dicomScript="scripts/dicom-filter.script"<br />
quarantine="quarantine-directory" /><br />
quarantineUncorrectedMismatches="no" /><br />
logUncorrectedMismatches="no" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomAnonymizer for temporary storage.<br />
*<b>dicomScript</b> specifies the path to an optional script file (in the same language as the DicomFilter), determining whether to process the object.<br />
*<b>quarantine</b> is a directory in which the DicomCorrector is to quarantine objects that generate quarantine calls during processing.<br />
*<b>quarantineUncorrectedMismatches</b> specifies whether to quarantine objects in which uncorrectable VR mismatches are detected. Values are "yes" and "no". The default is "no". <br />
*<b>logUncorrectedMismatches</b> specifies whether to make a log entry for each uncorrectable VR mismatch that is detected. Values are "yes" and "no". The default is "no". <br />
<br />
Notes:<br />
# The <b>dicomScript</b> specifies the instructions for determining whether to process the DicomObject. If this attribute is missing, all DicomObjects are accepted for processing. If the attribute is present, the computation must produce the value true for the DicomObject to be processed.<br />
# The computation specified in the <b>dicomScript</b> is performed on the unmodified dataset, so references to elements that may be corrected may produce unexpected results.<br />
<br />
=====DicomPixelAnonymizer=====<br />
The DicomPixelAnonymizer is a processor stage that blanks regions in DicomObjects which are images and passes all other object types unmodified. The DicomPixelAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the DicomAnonymizer is:<br />
<pre><br />
<DicomPixelAnonymizer<br />
name="DicomPixelAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomPixelAnonymizer"<br />
root="root-directory" <br />
log="no"<br />
script="scripts/dicom-pixel-anonymizer.script"<br />
setBurnedInAnnotation="no"<br />
test="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the DicomPixelAnonymizer for temporary storage.<br />
*<b>log</b> determines whether the signature matched by the DicomObject is to be listed in the log. Values are "yes" and "no". The default is "no". This feature is intended for use while debugging the script.<br />
*<b>script</b> specifies the path to the script for the DicomPixelAnonymizer.<br />
*<b>setBurnedInAnnotation</b> specifies whether to set the BurnedInAnnotation eledment (0028,0301) to "NO" if as matching signature is found. Values are "yes" and "no". The default is "no". If the value is "no", the element is left unmodified.<br />
*<b>test</b> specifies whether to set the color of blanked regions to black or gray. Values are "yes" and "no". The default is "no". If the value is "no", the regions are set to black. The purpose of this attribute is to make it easy to see what regions are being modified while testing a new script.<br />
*<b>quarantine</b> is a directory in which the DicomPixelAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
For information on the script language, see [[The CTP DICOM Pixel Anonymizer]].<br />
<br />
<b>Important notes: </b> <br />
* The DicomPixelAnonymizer can process all objects that do not contain encapsulated pixel data.<br />
* The DicomPixel anonymizer can also process objects that contain encapsulated pixel data with the JPEGBaseline transfer syntax (1.2.840.10008.1.2.4.50).<br />
* To allow objects containing encapsulated pixel data with other transfer syntaxes to be processed, include a DicomDecompressor stage before the DicomPixelAnonymizer. When including the DicomDecompressor stage, setting its skipJPEGBaseline attribute to "yes" will preserve the compression of JPEGBaseline objects.<br />
* The DicomPixelAnonymizer does not remove PHI from the non-pixel data in an object. To de-identify that data, include a DicomAnonymizer stage in the pipeline.<br />
<br />
=====XmlAnonymizer=====<br />
The XmlAnonymizer is a processor stage that anonymizes XmlObjects and passes all other object types unmodified. The XmlAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the XmlAnonymizer is:<br />
<pre><br />
<XmlAnonymizer<br />
name="XmlAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.XmlAnonymizer"<br />
root="root-directory" <br />
script="scripts/xml-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the XmlAnonymizer.<br />
*<b>quarantine</b> is a directory in which the XmlAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====ZipAnonymizer=====<br />
The ZipAnonymizer is a processor stage that anonymizes ZipObjects and passes all other object types unmodified. The ZipAnonymizer is configured with a script file. If a script file is either not configured or absent, objects are passed unmodified. The configuration element for the ZipAnonymizer is:<br />
<pre><br />
<ZipAnonymizer<br />
name="ZipAnonymizer"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.ZipAnonymizer"<br />
root="root-directory" <br />
script="scripts/zip-anonymizer.script" <br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the Anonymizer for temporary storage.<br />
*<b>script</b> specifies the path to the script for the ZipAnonymizer.<br />
*<b>quarantine</b> is a directory in which the ZipAnonymizer is to quarantine objects that generate quarantine calls during processing.<br />
<br />
=====EmailService=====<br />
The EmailService is a processor stage that sends emails when studies are received. An email is sent for each study, including the numbers of objects, series, and images in the study, as well as other information that is specified in the configuration element below. The configuration element for the EmailService is:<br />
<pre><br />
<EmailService<br />
name="EmailService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.EmailService"<br />
root="root-directory" <br />
script="scripts/EmailService.script" <br />
smtpServer="SMTP server URL"<br />
username=""<br />
password=""<br />
to=""<br />
from=""<br />
cc=""<br />
subject=""<br />
includePatientName="no"<br />
includePatientID="no"<br />
includeModality="no"<br />
includeStudyDate="no"<br />
includeAccessionNumber="no"<br />
logSentEmails="no"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the EmailService for temporary storage.<br />
*<b>script</b> specifies the path to the script for the EmailService. This script determines whether a DicomObject is to be considered by the stage.<br />
*<b>smtpServer</b> is the URL of the SMTP server to be used by the EmailService to send emails.<br />
*<b>username</b> is the username for authentication on the SMTP server. If blank, no authentication is done.<br />
*<b>password</b> is the password for authentication on the SMTP server. If the username is blank, the password is ignored.<br />
*<b>to</b> is the email address of the recipient of the emails. If multiple recipients are necessary, their addresses must be separated by commas.<br />
*<b>from</b> is the email address of the sender.<br />
*<b>cc</b> is the email address of the cc recipients. If multiple cc recipients are necessary, their addresses must be separated by commas.<br />
*<b>subject</b> is the text for the subject line. This can be used to identify the name of the trial.<br />
*<b>includePatientName</b> specifies whether to include the patient name in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includePatientID</b> specifies whether to include the patient ID in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeModality</b> specifies whether to include the modality in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeStudyDate</b> specifies whether to include the study date in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>includeAccessionNumber</b> specifies whether to include the study accession number in the email. Allowed values are <b>yes</b> and <b>no</b>. The default is <b>no</b>. <br />
*<b>quarantine</b> is a directory in which the EmailService is to quarantine objects if necessary.<br />
<br />
Notes:<br />
* The patient name, patient ID, modality, and study date values are those of the first image received for the study. These values may contain PHI if the EmailService stage occurs before the objects are anonymized, either at the source or in preceding stages in the pipeline.<br />
<br />
====Storage Services====<br />
=====FileStorageService=====<br />
The FileStorageService stores objects in a file system. It automatically defines subdirectories beneath its root directory and populates them accordingly. The configuration element for the StorageService is:<br />
<pre><br />
<FileStorageService<br />
name="FileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FileStorageService"<br />
root="D:/storage" <br />
type="month"<br />
timeDepth="0"<br />
acceptDuplicateUIDs="yes"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes" <br />
returnStoredFile="yes"<br />
setWorldReadable="no"<br />
setWorldWritable="no"<br />
fsNameTag="00097770"<br />
autoCreateUser="no"<br />
port="85"<br />
ssl="no"<br />
requireAuthentication="no"<br />
exportDirectory=""<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</FileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>type</b> determines the structure of the storage tree. The allowed values are:<br />
**<b>year</b>: root/FSNAME/year/studyName, e.g. root/2008/123.456.789<br />
**<b>month</b>: root/FSNAME/year/month/studyName, e.g. root/2008/06/123.456.789<br />
**<b>week</b>: root/FSNAME/year/week/studyName, e.g. root/2008/36/123.456.789<br />
**<b>day</b>: root/FSNAME/year/day/studyName, e.g. root/2008/341/123.456.789<br />
**<b>none</b>: root/FSNAME/studyName, e.g. root/123.456.789<br />
::(FSNAME is the name of the file system to which the study belongs. See the <b>fsNameTag</b> attribute below for additional information.)<br />
*<b>timeDepth</b> specifies the length of time in days that studies are stored. The default value is <b>0</b>, which means forever. If timeDepth is greater than zero, studies older than that value are automatically removed from storage.<br />
*<b>acceptDuplicateUIDs</b> determines whether objects with duplicate UIDs are to be stored under separate names or if a newer duplicate object is to overwrite an older one. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>setWorldReadable</b> determines whether the FileStorageService makes all files and directories readable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to access files without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>setWorldWritable</b> determines whether the FileStorageService makes all files and directories writable by all users. Values are "yes" and "no". The default is "no". This attribute should only be used if users or other programs are to be allowed to write files into the FileStorageService without using the FileStorageService web server. This feature is <b>not</b> recommended.<br />
*<b>fsNameTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is used to specify the name of the root directory's child under which to store a received object. If the attribute is missing from the configuration or if the specified element is missing from the received object, or if the contents of the specified element are blank, the object is stored under the "__default" tree.<br />
*<b>autoCreateUser</b> determines whether the StorageService is to create a user for each new value of the element specified by the fsNameTag. The default is "no". The user is created with both the username and the password set to the value of the element specified by the fsNameTag.<br />
*<b>port</b> specifies the port on which a web server is to be started to provide access to the stored studies. If the attribute is missing, no web server is started for the FileStorageService.<br />
*<b>ssl</b> determines whether the web server uses SSL. Values are "yes" and "no". The default is "no". <br />
*<b>requireAuthentication</b> determines whether users are forced to log in to the web server. Values are "yes" and "no". The default is "no".<br />
*<b>exportDirectory</b> specifies a directory into which the web server can copy files when the a user with the admin privilege clicks a link on the Study List page. This feature can be used to allow studies to be cached in the FileStorageService and then manually released to the DirectoryImportService of another pipeline for subsequent processing and/or export.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
For more information on the embedded web server in the FileStorageService, see [[The CTP FileStorageService Web Server]] and [[The CTP FileStorageService Access Mechanism]].<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# Below the root are directories called FileSystems. A FileSystem may be defined by the value of an element in the object being stored by using the fsNameTag attribute. If no FileSystem is defined by the object, it is stored in the default FileSystem (<b>__default</b>).<br />
# Within a FileSystem, studies are grouped depending on the value of the type attribute. For example, if the type attribute has the value "month", studies are organized by year and month, e.g. "2007/09".<br />
# At the bottom of the hierarchy are directories organized by StudyInstanceUID, thus grouping all objects received for a specific study together in one directory. <br />
# Objects are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
#*.md for FileObjects<br />
# Any object not containing a StudyInstanceUID or StudyUID is stored in the <b>bullpen</b> directory.<br />
# The <b>fsNameTag</b> attribute can be used to create storage trees based on element values like PatientID. It can also access elements in private groups, as might be done if the <b>calledAETTag</b> attribute of the DicomImportService is used to pass destination information. Similarly, the <b>callingAETTag</b> attribute of the DicomImportService could be used to pass source information, allowing separation of objects into FileSystems based on the sending system.<br />
# The <b>fsNameTag</b> attribute supports a list of element tags in the form <tt><b>fsNameTag=”00400275::00401001”</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. This feature allows the file system name to be obtained from an element buried in an item dataset that may be several levels down from the root dataset. Only the first item dataset is searched at each level.<br />
<br />
Notes on the <b>jpeg</b> child element:<br />
# The optional <b>jpeg</b> child element causes the FileStorageService to create one or more JPEG images for each DICOM image when it is stored. <br />
# The <b>jpeg</b> element should be included <b>only</b> when pre-computed JPEG images are required by an external application which directly references the disk drive containing the stored files (for example, the NBIA application).<br />
# When images are accessed through the FileStorageService web server's Storage Servlet or Ajax Servlet, they are produced dynamically, and <b>jpeg</b> elements are not required.<br />
# Multiple <b>jpeg</b> elements may appear if multiple images must be created (with different parameters) for each stored DICOM image.<br />
# The attributes specify the frame, width and quality parameters of the created image:<br />
#* The <b>frame</b> attribute which frame in multi-frame objects is to be saved. It has four allowed values: <b>first, middle, last, all</b>. The default is <b>first</b>. If <b>all</b> is selected and the StorageService supports saving all frames, then one JPEG image is created for each frame in the object. NOTE: The FileStorageService does not support the <b>frame</b> attribute and always behaves as if <b>frame="first"</b> is specified. The BasicFileStorageService fully supports the <b>frame</b> attribute.<br />
#* If the width of the parent DICOM image lies between the values of <b>wmax</b> and <b>wmin</b>, the width of the created image will be equal to the width of the parent.<br />
#*<b>wmax</b> specifies the maximum width of the created image. The default is 10000.<br />
#*<b>wmin</b> specifies the minimum width of the created image. The default is 96.<br />
#*The height of the created image is automatically computed to provide the same aspect ratio as the parent.<br />
#*<b>q</b> specifies the compression quality for the created image. Allowed values are <b>1</b> through <b>100</b>, with larger values producing better quality (and larger file sizes). The system default is triggered by specifying <b>-1</b>, which generally produces a good image.<br />
# A JPEG image file created in response to a <b>jpeg</b> child element is stored in the same directory as the parent DICOM image.<br />
# The filename of a created image is constructed from:<br />
#* the name of the parent file, <br />
#* a suffix in square brackets identifying the parameters used to create it, <br />
#* and a <b>.jpeg</b> extension. <br />
# The parameters appear in the order: <b>wmax</b>, <b>wmin</b>, <b>q</b>, and are separated by semicolons. <br />
# For example, a JPEG image created from <b>FO-29126.dcm</b> might have the name <b>FO-29126.dcm[400;96;-1].jpeg</b>.<br />
# If a 96-pixel wide thumbnail is required for an external application, the following <b>jpeg</b> child element could be specified:<br />
<pre><br />
<jpeg wmax="96" wmin="96" q="-1" /><br />
</pre><br />
<br />
=====BasicFileStorageService=====<br />
The BasicFileStorageService stores objects in a file system. It provides no organization of the files and no means of access to them. It is intended for use in situations where direct file access is provided through an external application like NBIA. The configuration element for the StorageService is:<br />
<pre><br />
<BasicFileStorageService<br />
name="BasicFileStorageService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.BasicFileStorageService"<br />
index="D:/storage"<br />
root="D:/storage/root" <br />
nLevels="3" <br />
maxSize="200" <br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
returnStoredFile="yes"<br />
logDuplicates="no"<br />
rejectDuplicates="no"<br />
acceptClones="yes"<br />
quarantine="quarantine-directory" ><br />
<br />
<jpeg frame="first" wmax="10000" wmin="96" q="-1" /><br />
<br />
</BasicFileStorageService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>index</b> is the directory in which the index is stored.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>nLevels</b> defines the depth of the storage tree. The default is 3.<br />
*<b>maxSize</b> defines the maximum number of files or directories in each node of the storage tree. The default is 200.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be stored. Values are "yes" and "no". The default is "yes".<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>logDuplicates</b> specifies whether an entry is to be made in the log whenever a file is received which has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no".<br />
*<b>rejectDuplicates</b> specifies whether a file is to be quarantined (and not saved) if it has the same SOPInstanceUID as a file which has already been stored. Values are "yes" and "no". The default is "no". See <b>acceptClones</b> below.<br />
*<b>acceptClones</b> specifies whether a file is to be accepted even if it has the same SOPInstanceUID as a file which has already been stored, provided that it is identical to the previously stored file. Values are "yes" and "no". The default is "yes". See the special notes on this attribute below.<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# Files are stored in a tree of directories with the root of the tree as defined in the root attribute of the configuration element. <br />
# The index directory must not appear under the root directory. A convenient approach is shown in the example above, where the root directory appears under the index directory.<br />
# The number of files which will be stored under any directory in the root is maxSize**(nLevels-1). For the default values of the nLevels and maxSize parameters (3 and 200), this is 40,000. <br />
# Directories are created at the top level (root) when existing directories are full. There is no maximum number of top-level directories; however, it is wise to consider the number of objects which are expected to be stored and to select values of nLevels and maxSize which would keep the number of top-level directories below 1000.<br />
# For storage requirements of 10 million files, the default values of nLevels and maxSize are fine.<br />
# For storage requirements of 10 billion files, nLevels="4" and maxSize="300" would work well.<br />
# Files are stored as leaves at the bottom of the tree.<br />
# No organization into related groups (e.g. by StudyInstanceUID) is provided. <br />
# Files are indexed by UID (e.g., SOPInstanceUID).<br />
# A duplicate object (e.g., one whose UID matches the UID of an object already stored) overwrites the stored object in the same place in the storage system (e.g., the same directory and the same filename), and any required <b>jpeg</b> images are recreated, overwriting the previously stored ones.<br />
# FileObjects, which do not contain UIDs, are not stored; they are simply passed to the next stage.<br />
# Files are stored with standard file extensions:<br />
#*.dcm for DicomObjects<br />
#*.xml for XmlObjects<br />
#*.zip for ZipObjects<br />
# See the section on the FileStorageService for a description of the <b>jpeg</b> child element.<br />
# If <b>jpeg</b> child elements appear, the files which they create are <b>not</b> counted against the maxSize parameter. Thus, if maxSize is 200 and two <b>jpeg</b> child elements appear, the bottom directories in the tree could contain 600 files. If <b>frame="all"</b> is specified and multi-frame objects are to be processed, this could result in many times that number. In situations where a given choice of maxSize could result in more than 1000 files in one directory, it is advisable to reduce maxSize and increase nLevels.<br />
<br />
Notes on the use of the <b>logDuplicates</b>, <b>rejectDuplicates</b>, and <b>acceptClones</b>:<br />
* The default operation is to overwrite a stored file if another file is subsequently received with the same UID.<br />
* If it is desired to suppress the storage and subsequent processing of files that have the same UIDs as previously stored files, the <b>rejectDuplicates</b> attribute must be set to "yes".<br />
* If it is desired only to suppress the storage and subsequent processing of files that have the same UIDs but are not identical to the previously stored files, then the <b>acceptClones</b> attribute must be set to "no".<br />
* The operation of the <b>rejectDuplicates</b> and <b>acceptClones</b> attributes is not affected gy the settin gof the <b>logDuplicates</b> attribute.<br />
<br />
=====DirectoryStorageService=====<br />
The DirectoryStorageService stores DicomObjects in a directory structure with no index. It optionally organizes the objects in subdirectories according to a list of element tags. The organization can be obtained either from the current object or from an object that had been cached in another stage. This StorageService is intended for use in situations where files are passed to an external application like the Edge Server in the RSNA Image Sharing Project. It can also be used to pass files to DirectoryImportService stages in other pipelines. The configuration element for the StorageService is:<br />
<pre><br />
<DirectoryStorageService<br />
name="DirectoryStorageService"<br />
id="stage ID"<br />
dicomScript="scripts/dss.script"<br />
cacheID="cache stage ID"<br />
structure="dir1/dir2/dir3/..."<br />
defaultString="UNKNOWN"<br />
whitespaceReplacement="_"<br />
class="org.rsna.ctp.stdstages.DirectoryStorageService"<br />
root="D:/storage/root" <br />
setStandardExtensions="no"<br />
filenameTag=""<br />
acceptDuplicates="yes"<br />
returnStoredFile="yes"<br />
quarantine="quarantine-directory" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>dicomScript</b> specifies the path to a script that examines the contents of a DicomObject and determines whether the object is to be accepted for storage. If the attribute is missing, all objects are accepted.<br />
*<b>cacheID</b> is the ID of an ObjectCache stage that can supply an object from which to obtain values to populate the directory names in the storage hierarchy. If this attribute is missing, the values are obtained from the current object.<br />
*<b>root</b> is the root directory of the storage tree.<br />
*<b>structure</b> is an optional sequence of directory names specifying the hierarchy of the storage tree. Directories in the sequence are separated by slashes. Each directory name in the sequence can consist of text and/or DICOM tags. If a directory name in the sequence includes one or more DICOM tags, the values of the corresponding elements in the current (or cached) DICOM object are substituted in the directory name for the tags. See the notes below for more details and examples of directory structures. If this attribute is missing, all files are stored in the root directory.<br />
*<b>defaultString</b> specifies a string used in place of a DICOM tag if the corresponding element is either missing or empty. If this attribute is missing, "UNKNOWN" is used.<br />
*<b>whitespaceReplacement</b> specifies a string used to replace whitespace, slash, or backslash characters in a directory name. If this attribute is missing, the underscore character is used.<br />
*<b>setStandardExtensions</b> specifies whether the stored files are to be assigned file extensions based on their file types (".dcm" for DicomObjects, ".xml" for XmlObjects, ".zip" for ZipObjects. and ".md" for all other object types). Values are "yes" and "no". The default is "no".<br />
*<b>filenameTag</b> specifies a DICOM element from which to obtain a filename to use in the storage of the file. If this attribute is missing or if it references an element that is not present (or is empty), the SOPInstanceUID is used for the filename.<br />
*<b>acceptDuplicates</b> specifies whether a file with the same name as an existing file is to overwrite the existing file or is to be saved with a different name. Values are "yes" and "no". The default is "yes", which means that all files are to be kept, creating new names when necessary.<br />
*<b>returnStoredFile</b> specifies whether the original object or a new object pointing to the file in the storage system is to be returned for processing by subsequent stages. Values are "yes" and "no". The default is "yes".<br />
*<b>quarantine</b> is a directory in which the StorageService is to quarantine objects that cannot be stored.<br />
<br />
Notes:<br />
# The stored object's SOPInstanceUID is used as the file name.<br />
# No file extension is appended to the SOPInstanceUID when creating the file name unless setStandardExtensions is set to "yes".<br />
# In directory names, DICOM tags are hex integers, formatted in parentheses or square brackets. Tags may optionally include commas to separate the group and element numbers. Leading zeroes are good form but not required in group numbers. Leading zeroes are required in element numbers. Commas are removed before parsing tags, so <b><tt>(20,D)</tt></b> is not equivalent to <b><tt>(20,000D)</tt></b>.<br />
# This example shows tags for PatientID/AccessionNumber/StudyInstanceUID: <b><tt>(0010,0020)/[00080050]/(0020,000D)</tt></b>.<br />
# This example shows how text and multiple tags can be combined in a single directory name: <b><tt>(0010,0020)/(0020,000D) - [00080050]</tt></b>. In this case the PatientID is used as the top-level directory, with a subdirectory consisting of the StudyInstanceUID, a space, a hyphen, another space, and the AccessionNumber.<br />
# Whitespace replacement is performed on all the text of a directory name, after substitution of the DICOM element values for any tags in the name, so in the example in the previous note, the separator between the StudyInstanceUID and the AccessionNumber would actually appear in the directory name as "_-_".<br />
# DICOM tags in directory names can include references to elements in sequence element item datasets in the form <tt><b>(0040,0275)::(0040,1001)</b></tt>. There is no limit to the number of tags in the sequence. All but the last tag must refer to SQ elements. Only the first item dataset is searched at each level.<br />
<br />
====Export Services====<br />
=====HttpExportService=====<br />
The HttpExportService queues objects and transmits them via HTTP with Content-Type <b>application/x-mirc</b>. The configuration element for the HttpExportService is:<br />
<pre><br />
<HttpExportService<br />
name="HttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.HttpExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
zip="no"<br />
sendDigestHeader="no"<br />
username="username"<br />
password="password"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>zip</b> determines whether files will be zipped before transmission (<b>yes</b>) or not (<b>no</b>). The default is <b>no</b>. This feature is intended for use with the HttpImportService.<br />
*<b>sendDigestHeader</b> determines whether a Digest header is to be included in the connection, allowing the destination to detect errors at the application level. (<b>yes</b> or <b>no</b>). The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#If a proxy server is not in use, the proxy attributes must be omitted.<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====PolledHttpExportService=====<br />
The PolledHttpExportService queues objects and transmits them in the HTTP response stream of a received connection. Files are transmitted with Content-Type equal to <b>application/x-mirc</b>. This ExportService is designed to work in conjunction with the PollingHttpImportService to allow penetration of a firewall without having to open an inbound port, as described in [[#Security Issues | Security Issues]]. The configuration element for the Polled HttpExportService is:<br />
<pre><br />
<PolledHttpExportService<br />
name="PolledHttpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.PolledHttpExportService"<br />
root="root-directory" <br />
port="listening-port"<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"><br />
<br />
<accept ip="..."/><br />
<reject ip="..."/><br />
<br />
</PolledHttpExportService><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>port</b> is the port on which the ExportService listens for connections.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*The <b>accept</b> child element can be used to specify a white list of IP addresses determining which connections are to be accepted. One <b>accept</b> child element must appear for each IP address in the white list. If the white list is empty, the white list is not used to filter connections.<br />
*The <b>reject</b> child element can be used to specify black lists of IP addresses determining which connections are to be rejected. One <b>reject</b> child element must appear for each IP address in the black list. If the black list is empty, the black list is not used to filter connections.<br />
*For a connection to be accepted, the IP address of the remote client must be accepted by the white list and and not rejected by the black list.<br />
<br />
Notes:<br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The PolledHttpExportService does not support SSL.<br />
<br />
=====DicomExportService=====<br />
The DicomExportService queues objects and transmits them to a DICOM Storage SCP. The configuration element for the DicomExportService is:<br />
<pre><br />
<DicomExportService<br />
name="DicomExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomExportService"<br />
root="root-directory" <br />
quarantine="quarantine-directory"<br />
auditLogID=""<br />
auditLogTags=""<br />
url="dicom://DestinationAET:ThisAET@ipaddress:port"<br />
associationTimeout="0"<br />
forceClose="no"<br />
hostTag="00097774" <br />
portTag="00097776" <br />
calledAETTag="00097770" <br />
callingAETTag="00097772"<br />
dicomScript="scripts/df.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
throttle="0"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage. This attribute is required only when the stage is accessed by other stages. Its value, when supplied, must be unique across all pipelines.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>quarantine</b> is a directory in which the DicomExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination DICOM Storage SCP (usually because a presentation context could not be negotiated). Such objects would always fail, so they must be removed from the export queue. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>auditLogID</b> specifies the ID of an AuditLog plugin. If this attribute is not empty, and if an AuditLog plugin is configured with that ID, an entry is made in the AuditLog for each successful transmission.<br />
*<b>auditLogTags</b> specifies the elements from the transmitted objects that are to be included in the AuditLog entry. Elements can be specified by their dcm4che names or their numeric values. Elements must be separated by semicolons. This is an example of several elements, including one from a private group: <br />
::<tt><b>auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber;(0009,7790)"</b></tt><br />
*<b>url</b> specifies the destination DICOM Storage SCP's URL.<br />
*<b>associationTimeout</b> specifies the length of time an association is to be left open after a transfer before it is closed automatically. Allowed valuers are <b>yes</b> and <b>no</b>. The default value is <b>no</b>. This parameter can be set to <b>yes</b> if it appears that the destination SCP is resetting the association and causing a problem with transfers.<br />
*<b>forceClose</b> specifies whether the DICOM association is to be closed after each transfer. The value is specified in seconds. A value of zero (the default) means to disable the automatic association closing mechanism.<br />
*<b>hostTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the host name (or IP address) of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>portTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the port of the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the host specified in the <b>url</b> attribute. <br />
*<b>calledAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the receiver in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute. <br />
*<b>callingAETTag</b> is an optional DICOM element, specified in hex with no comma separating the group and element numbers, which is to be used by the DicomExportService to obtain the AE Title which specifies the sender in the association. If the attribute is missing or zero, or if the value does not parse as a hex integer, or if the identified element does not exist in a DicomObject being exported, the DicomExportService uses the AE Title specified in the <b>url</b> attribute.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>throttle</b> sets the minimum time (in milliseconds) between exports to the destination. The default is 0 milliseconds. The maximum allowed value is 5 seconds.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue. The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
Notes:<br />
*For an object to be accepted for export, the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] for information about the script language.<br />
<br />
=====DicomSTOWRSExportService=====<br />
The DicomSTOWRSExportService queues objects and transmits them via the DICOM STOW-RS protocol. The configuration element for the DicomSTOWRSExportService is:<br />
<pre><br />
<DicomSTOWRSExportService<br />
name="DicomSTOWRSExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.DicomSTOWRSExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
includeContentDispositionHeader="no"<br />
username="username"<br />
password="password"<br />
dicomScript="scripts/df.script"<br />
logDuplicates="no"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination system's URL.<br />
*<b>includeContentDispositionHeader</b> determines whether a Content-Disposition header is to be included in the connection. This header is not required in the protocol, but in some cases, it may be useful. Allowed values are <b>yes</b> or <b>no</b>. The default is <b>no</b>.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. This allows an HttpImportService to authenticate transmissions. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>logDuplicates</b> specifies whether to make a log entry for each object whose UID matches that of any other object in the last 20 that have been exported. This capability is intended primarily for configuration debugging.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
<br />
Notes: <br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The protocol part of the <b>url</b> can be <b>http</b> or <b>https</b>, the latter causing connections to be initiated using secure sockets layer.<br />
#For an object to be accepted for export, the object must be a DicomObject <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
<br />
=====FtpExportService=====<br />
The FtpExportService queues objects and transmits them to an FTP server. The configuration element for the FtpExportService is:<br />
<pre><br />
<FtpExportService<br />
name="FtpExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.FtpExportService"<br />
root="root-directory" <br />
url="ftp://ipaddress:port/path"<br />
username="..."<br />
password="..."<br />
acceptDicomObjects="yes"<br />
acceptXmlObjects="yes"<br />
acceptZipObjects="yes"<br />
acceptFileObjects="yes"<br />
dicomScript="scripts/df.script"<br />
xmlScript="scripts/xf.script"<br />
zipScript="scripts/zf.script"<br />
auditLogID="id"<br />
auditLogTags="PatientID;SOPInstanceUID;StudyInstanceUID;InstanceNumber"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination FTP server's URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the FTP listener listens. The default port is 21.<br />
**<b>path</b> is the base directory on the FTP server in which the FtpExportService will create StudyInstance directories.<br />
*<b>username</b> specifies the username under which the FtpExportService will log in to the FTP server.<br />
*<b>password</b> specifies the password to be used in the login process.<br />
*<b>acceptDicomObjects</b> determines whether DicomObjects are to be exported.<br />
*<b>acceptXmlObjects</b> determines whether XmlObjects are to be exported.<br />
*<b>acceptZipObjects</b> determines whether ZipObjects are to be exported.<br />
*<b>acceptFileObjects</b> determines whether FileObjects are to be exported.<br />
*<b>dicomScript</b> specifies the path to a script which examines the contents of a DicomObject and determines whether the object is to be exported.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>zipScript</b> specifies the path to a script which examines the contents of a ZipObject and determines whether the object is to be exported.<br />
*<b>auditLogID</b> is the value of the <b><tt>id</tt></b> attribute of an AuditLog plugin in which to log exported DICOM objects. If this attribute is missing or if the value does not correspond to an AuditLog plugin, no audit logging is performed.<br />
*<b>auditLogTags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as <b><tt>dcm4che</tt></b> element names or in standard DICOM notation, e.g. <b><tt>(0008,0050)</tt></b>.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#For an object to be accepted for export, the object type must be accepted (e.g., acceptDicomObjects="yes") <u>and</u> the object must pass the script test. If the script attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP DICOM Filter]] and [[The CTP XML and Zip Filters]] for information about the script languages.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
#The FtpExportService stores files in subdirectories of the <b>path</b> part of the URL, organized by StudyInstanceUID (or StudyUID in the case of non-DICOM files). Files not containing a StudyUID are stored in the <b>bullpen</b> directory under the <b>path</b> directory.<br />
#If the directory specified by the <b>path</b> does not exist, it is created.<br />
#Files are stored within their directories with names that consist of the date and time (to the millisecond) when they were transferred to the server.<br />
#If a file is transmitted multiple times, multiple copies of the file will appear with its directory, each with the date/time of the transfer.<br />
#No index of the studies and files is created on the server.<br />
<br />
=====AimExportService=====<br />
The AimExportService queues objects and transmits them to an AIM Data Service. The configuration element for the AimExportService is:<br />
<pre><br />
<AimExportService<br />
name="AimExportService"<br />
id="stage ID"<br />
class="org.rsna.ctp.stdstages.AimExportService"<br />
root="root-directory" <br />
url="http://ipaddress:port/path"<br />
username="username"<br />
password="password"<br />
xmlScript="scripts/xf.script"<br />
logResponses="none"<br />
quarantine="quarantine-directory"<br />
interval="5000" /><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>id</b> is any text to be used to uniquely identify the stage.<br />
*<b>root</b> is a directory for use by the ExportService for internal storage and queuing.<br />
*<b>url</b> specifies the destination AIM Data Service URL:<br />
**<b>ipaddress</b> can be a numeric address or a domain name.<br />
**<b>port</b> is the port on which the AIM Data Service listens.<br />
**<b>path</b> is the path identifying the AIM Data Service on the destination server.<br />
*<b>username</b> specifies the username credential for inclusion in the header during the transmission. If the username attribute is not present or has a whitespace value, no header is generated.<br />
*<b>password</b> specifies the password credential for inclusion in the header during the transmission.<br />
*<b>xmlScript</b> specifies the path to a script which examines the contents of an XmlObject and determines whether the object is to be exported.<br />
*<b>logResponses</b> specifies whether the contents of the response from the AIM Data Service are to be entered into the CTP log file. The recognized values are:<br />
** <b>all</b> - log all responses<br />
** <b>failed</b> - log only the responses that indicate that the Data Service rejected the object<br />
** <b>none</b> - do not log responses.<br />
The default, if the attribute is missing or has any other value, is not to log.<br />
*<b>quarantine</b> is a directory in which the AimExportService is to quarantine objects that fail to be transmitted because they were rejected by the destination AIM Data Service. If no quarantine directory is specified, failed objects are deleted.<br />
*<b>interval</b> is the sleep time (in milliseconds) between polls of the export queue.<br />
Notes: <br />
#The AimExportService only transmits XmlObjects. It ignores all other object types.<br />
#The AimExportService only transmits XmlObjects whose root element is "ImageAnnotation".<br />
#The XmlObject must pass the script test. If the <b>xmlScript</b> attribute is not supplied, the test returns true by default and the object is accepted. See [[The CTP XML and Zip Filters]] for information about the script language.<br />
#The default interval is 5 seconds. The minimum allowed value is one second. The maximum allowed value is 10 seconds.<br />
<br />
=====DicomDifferenceLogger=====<br />
The DicomDifferenceLogger queues objects containing the changes made to DicomObjects processed by its pipeline and submits them to a LogAdapter class written specially to connect to an external database. The configuration element for the DicomDifferenceLogger is:<br />
<pre><br />
<DicomDifferenceLogger<br />
name="DicomDifferenceLogger"<br />
class="org.rsna.ctp.stdstages.DicomDifferenceLogger"<br />
root="roots/DicomDifferenceLogger"<br />
adapterClass="..."<br />
cacheID="ObjectCache"<br />
tags="PatientID;PatientName;SOPInstanceUID"/><br />
</pre><br />
where:<br />
*<b>name</b> is any text to be used as a label on configuration and status pages.<br />
*<b>root</b> is a directory for use by the DicomDifferenceLogger for temporary storage.<br />
*<b>adapterClass</b> is the class name of the external log's adapter class. See [[Developing a DicomDifferenceLogger LogAdapter]] for more information.<br />
*<b>tags</b> is a semicolon-separated list of DICOM element tags whose values are to be included in the AuditLog entry. Tags can be specified as dcm4che element names (DICOM keywords) or in standard DICOM notation, e.g. (0008,0050).<br />
*<b>cacheID</b> is the ID of an ObjectCache stage.<br />
<br />
==Security Issues==<br />
In a clinical trial, transmission of data from image acquisition sites to the principal investigator site involves penetrating at least one firewall. Since the image acquisition site initiates an outbound connection, this only rarely requires special action. At the principal investigator's site, where the connection is inbound, some provision must be made to allow the connection to reach its destination. There are two basic solutions. The simplest solution is to open a port in the firewall at the principal investigator's site and route connections for that port to the computer running the CTP application. In some institutions, however, security policies prohibit this solution. The alternative is to use the PolledHttpExportService and PollingHttpImportService to allow data to flow without having to open any ports on the internal network to inbound connections.<br />
<br />
Using this latter solution requires two computers, each running CTP. One computer is placed in the border router's DMZ with one port open to the internet, allowing connections to the HttpImportService of the program running in that computer. That program's pipeline includes a PolledHttpExportService which queues objects and waits for a connection before passing them onward. The second computer is placed on the internal network. Its program has a pipeline which starts with a PollingHttpImportService. That ImportService is configured to make outbound connections to the DMZ computer when a file is requested. This allows files to pass through the firewall on the response stream of the outbound connection without having to open any ports to the internal network.<br />
<br />
==Notes==<br />
<br />
===Java Cryptography Extension===<br />
The anonymizer pipeline stages (DicomAnonymizer, XmlAnonymizer, and ZipAnonymizer) use classes in the Java Cryptography Extension (JCE). The JCE has been included in the Java JRE since at least Java 1.5. To enable the use of the JCE, an entry must appear in the <b><tt>Java/jre/lib/security/java.security</tt></b> file. In the latest Java versions, the entry is automatically included. The most recent versions include a section in the file that looks like this:<br />
<pre><br />
# There must be at least one provider specification in java.security.<br />
# There is a default provider that comes standard with the JDK. It<br />
# is called the "SUN" provider, and its Provider subclass<br />
# named Sun appears in the sun.security.provider package. Thus, the<br />
# "SUN" provider is registered via the following:<br />
#<br />
# security.provider.1=sun.security.provider.Sun<br />
#<br />
# (The number 1 is used for the default provider.)<br />
#<br />
# Note: Providers can be dynamically registered instead by calls to<br />
# either the addProvider or insertProviderAt method in the Security<br />
# class.<br />
#<br />
# List of providers and their preference orders (see above):<br />
#<br />
security.provider.1=sun.security.provider.Sun<br />
security.provider.2=sun.security.rsa.SunRsaSign<br />
security.provider.3=com.sun.net.ssl.internal.ssl.Provider<br />
security.provider.4=com.sun.crypto.provider.SunJCE<br />
security.provider.5=sun.security.jgss.SunProvider<br />
security.provider.6=com.sun.security.sasl.Provider<br />
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI<br />
security.provider.8=sun.security.smartcardio.SunPCSC<br />
security.provider.9=sun.security.mscapi.SunMSCAPI<br />
</pre><br />
On older Javas, it appears that there are no <b><tt>security.provider...</tt></b> lines in the file. If no provider is specified, the anonymizer will crash when it tries to load a JCE class. If that happens, you will see an error in the Launcher's Console tab. You can either edit the <b><tt>Java/jre/lib/security/java.security</tt></b> file and add the <b><tt>security.provider...</tt></b> lines shown above or uninstall Java and get the latest version.<br />
<br />
===Important Note for Unix/Linux Platforms===<br />
Unix and its derivatives require that applications listening on ports with numbers less than 1024 have special privileges. On such systems, it might be best to put all import services and all web servers on ports above this value. The default configuration puts the web server on port 80 for Windows platforms because that is the default port for the web. On Linux platforms, the default configuration puts the web server on port 1080. This can be changed easily in the CTP-launcher application when CTP is started.<br />
<br />
===ImageIO Tools for Macintosh===<br />
The Java Advanced Imaging ImageIO Tools is a component which provides methods for creating and reading image files. It supports many image file types, and it is designed to be extensible. The authors (Gunter Zeilinger, et al.) of the DICOM toolkit (dcm4che) used by CTP extended the ImageIO Tools to support DICOM.<br />
<br />
The ImageIO Tools consists of two parts, a top-level library written in Java and runnable on any platform, and a native library which implements certain compression/decompression functions. The latter library is unique to each platform.<br />
<br />
The top-level library consists of two files:<br />
* jai_imageio.jar<br />
* clibwrapper_jiio.jar<br />
<br />
There is no Macintosh installer for the ImageIO Tools. You can obtain the two files above by getting the zip file for a Linux installation and unpacking it. Place the two files into <b><tt>/System/Library/Java/Extensions</tt></b>. <br />
<br />
There is no native library available for the Macintosh. <br />
<br />
For more information on the ImageIO Tools, see this [http://mircwiki.rsna.org/index.php?title=Java_Advanced_Imaging_ImageIO_Tools article].</div>Johnperry