PageRenderTime 56ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/ClearCanvas/Dicom/Utilities/StudyBuilder/StudyNode.cs

https://github.com/scottshea/monodicom
C# | 302 lines | 172 code | 37 blank | 93 comment | 15 complexity | e8301e79f0ca693fcc6b29caa1503daf MD5 | raw file
  1. #region License
  2. // Copyright (c) 2010, ClearCanvas Inc.
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without modification,
  6. // are permitted provided that the following conditions are met:
  7. //
  8. // * Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. // * Neither the name of ClearCanvas Inc. nor the names of its contributors
  14. // may be used to endorse or promote products derived from this software without
  15. // specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  19. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  21. // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  22. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  23. // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  25. // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  26. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  27. // OF SUCH DAMAGE.
  28. #endregion
  29. using System;
  30. using ClearCanvas.Dicom;
  31. namespace ClearCanvas.Dicom.Utilities.StudyBuilder
  32. {
  33. /// <summary>
  34. /// A <see cref="StudyBuilderNode"/> representing a study-level data node in the <see cref="StudyBuilder"/> tree hierarchy.
  35. /// </summary>
  36. public sealed class StudyNode : StudyBuilderNode
  37. {
  38. private readonly SeriesNodeCollection _series;
  39. private string _instanceUid;
  40. private string _description;
  41. private DateTime? _dateTime;
  42. private string _accessionNum;
  43. private string _studyId;
  44. /// <summary>
  45. /// Constructs a new <see cref="StudyNode"/> using default values.
  46. /// </summary>
  47. public StudyNode()
  48. {
  49. _series = new SeriesNodeCollection(this);
  50. _instanceUid = StudyBuilder.NewUid();
  51. _studyId = string.Format("ST{0}", this.Key);
  52. _description = "Untitled Study";
  53. _dateTime = System.DateTime.Now;
  54. _accessionNum = "";
  55. }
  56. /// <summary>
  57. /// Constructs a new <see cref="StudyNode"/> using the specified study ID and default values for everything else.
  58. /// </summary>
  59. /// <param name="studyId">The desired study ID.</param>
  60. public StudyNode(string studyId) : this()
  61. {
  62. _studyId = studyId;
  63. }
  64. /// <summary>
  65. /// Constructs a new <see cref="StudyNode"/> using actual values from attributes in the given <see cref="DicomAttributeCollection"/>.
  66. /// </summary>
  67. /// <param name="dicomDataSet">The data set from which to initialize this node.</param>
  68. public StudyNode(DicomAttributeCollection dicomDataSet)
  69. {
  70. _series = new SeriesNodeCollection(this);
  71. _studyId = dicomDataSet[DicomTags.StudyId].GetString(0, "");
  72. _description = dicomDataSet[DicomTags.StudyDescription].GetString(0, "");
  73. _dateTime = DicomConverter.GetDateTime(dicomDataSet[DicomTags.StudyDate].GetDateTime(0), dicomDataSet[DicomTags.StudyTime].GetDateTime(0));
  74. _accessionNum = dicomDataSet[DicomTags.AccessionNumber].GetString(0, "");
  75. _instanceUid = dicomDataSet[DicomTags.StudyInstanceUid].GetString(0, "");
  76. if (_instanceUid == "")
  77. _instanceUid = StudyBuilder.NewUid();
  78. }
  79. /// <summary>
  80. /// Copy constructor
  81. /// </summary>
  82. /// <param name="source"></param>
  83. /// <param name="copyDescendants"></param>
  84. public StudyNode(StudyNode source, bool copyDescendants) {
  85. _series = new SeriesNodeCollection(this);
  86. _instanceUid = StudyBuilder.NewUid();
  87. _studyId = source._studyId;
  88. _description = source._description;
  89. _dateTime = source._dateTime;
  90. _accessionNum = source._accessionNum;
  91. if(copyDescendants)
  92. {
  93. foreach (SeriesNode series in source._series)
  94. {
  95. _series.Add(series.Copy(true));
  96. }
  97. }
  98. }
  99. #region Misc
  100. /// <summary>
  101. /// Gets the parent of this node, or null if the node is not in a study builder tree.
  102. /// </summary>
  103. public new PatientNode Parent {
  104. get { return base.Parent as PatientNode; }
  105. internal set { base.Parent = value; }
  106. }
  107. #endregion
  108. #region Data Properties
  109. /// <summary>
  110. /// Gets or sets the study instance UID.
  111. /// </summary>
  112. public string InstanceUid
  113. {
  114. get { return _instanceUid; }
  115. internal set
  116. {
  117. if (_instanceUid != value)
  118. {
  119. if(string.IsNullOrEmpty(value))
  120. value = StudyBuilder.NewUid();
  121. _instanceUid = value;
  122. FirePropertyChanged("InstanceUid");
  123. }
  124. }
  125. }
  126. /// <summary>
  127. /// Gets or sets the study ID.
  128. /// </summary>
  129. public string StudyId
  130. {
  131. get { return _studyId; }
  132. set
  133. {
  134. if(_studyId != value)
  135. {
  136. _studyId = value;
  137. FirePropertyChanged("StudyId");
  138. }
  139. }
  140. }
  141. /// <summary>
  142. /// Gets or sets the study description.
  143. /// </summary>
  144. public string Description
  145. {
  146. get { return _description; }
  147. set
  148. {
  149. if(_description != value)
  150. {
  151. _description = value;
  152. FirePropertyChanged("Description");
  153. }
  154. }
  155. }
  156. /// <summary>
  157. /// Gets or sets the study date/time stamp.
  158. /// </summary>
  159. public DateTime? DateTime
  160. {
  161. get { return _dateTime; }
  162. set
  163. {
  164. if(_dateTime != value)
  165. {
  166. _dateTime = value;
  167. FirePropertyChanged("DateTime");
  168. }
  169. }
  170. }
  171. /// <summary>
  172. /// Gets or sets the accession number.
  173. /// </summary>
  174. public string AccessionNumber
  175. {
  176. get { return _accessionNum; }
  177. set
  178. {
  179. if(_accessionNum != value)
  180. {
  181. _accessionNum = value;
  182. FirePropertyChanged("AccessionNumber");
  183. }
  184. }
  185. }
  186. #endregion
  187. #region Update Methods
  188. /// <summary>
  189. /// Writes the data in this node into the given <see cref="DicomAttributeCollection"/>
  190. /// </summary>
  191. /// <param name="dicomDataSet">The data set to write data into.</param>
  192. internal void Update(DicomAttributeCollection dicomDataSet, bool writeUid)
  193. {
  194. dicomDataSet[DicomTags.StudyId].SetStringValue(_studyId);
  195. dicomDataSet[DicomTags.StudyDescription].SetStringValue(_description);
  196. dicomDataSet[DicomTags.AccessionNumber].SetStringValue(_accessionNum);
  197. DicomConverter.SetDate(dicomDataSet[DicomTags.StudyDate], _dateTime);
  198. DicomConverter.SetTime(dicomDataSet[DicomTags.StudyTime], _dateTime);
  199. if (writeUid)
  200. dicomDataSet[DicomTags.StudyInstanceUid].SetStringValue(_instanceUid);
  201. }
  202. #endregion
  203. #region Copy Methods
  204. /// <summary>
  205. /// Creates a new <see cref="StudyNode"/> with the same node data, nulling all references to other nodes.
  206. /// </summary>
  207. /// <returns>A copy of the node.</returns>
  208. public StudyNode Copy() {
  209. return this.Copy(false, false);
  210. }
  211. /// <summary>
  212. /// Creates a new <see cref="StudyNode"/> with the same node data, nulling all references to nodes outside of the copy scope.
  213. /// </summary>
  214. /// <param name="copyDescendants">Specifies that all the descendants of the node should also be copied.</param>
  215. /// <returns>A copy of the node.</returns>
  216. public StudyNode Copy(bool copyDescendants) {
  217. return this.Copy(copyDescendants, false);
  218. }
  219. /// <summary>
  220. /// Creates a new <see cref="StudyNode"/> with the same node data.
  221. /// </summary>
  222. /// <param name="copyDescendants">Specifies that all the descendants of the node should also be copied.</param>
  223. /// <param name="keepExtLinks">Specifies that references to nodes outside of the copy scope should be kept. If False, all references are nulled.</param>
  224. /// <returns>A copy of the node.</returns>
  225. public StudyNode Copy(bool copyDescendants, bool keepExtLinks) {
  226. return new StudyNode(this, copyDescendants);
  227. }
  228. #endregion
  229. #region Insert Methods
  230. /// <summary>
  231. /// Convenience method to insert SOP instance-level data nodes into the study builder tree under this study, creating a <see cref="SeriesNode">series</see> node if necessary.
  232. /// </summary>
  233. /// <param name="sopInstances">An array of <see cref="SopInstanceNode"/>s to insert into the study builder tree.</param>
  234. public void InsertSopInstance(SopInstanceNode[] sopInstances)
  235. {
  236. SeriesNode series = new SeriesNode();
  237. this.Series.Add(series);
  238. foreach (SopInstanceNode node in sopInstances)
  239. {
  240. series.Images.Add(node);
  241. }
  242. }
  243. /// <summary>
  244. /// Convenience method to insert series-level data nodes into the study builder tree under this study.
  245. /// </summary>
  246. /// <param name="series">An array of <see cref="SeriesNode"/>s to insert into the study builder tree.</param>
  247. public void InsertSeries(SeriesNode[] series)
  248. {
  249. foreach (SeriesNode node in series)
  250. {
  251. this.Series.Add(node);
  252. }
  253. }
  254. #endregion
  255. #region Series Collection
  256. /// <summary>
  257. /// Gets a list of all the <see cref="SeriesNode"/>s that belong to this study.
  258. /// </summary>
  259. public SeriesNodeCollection Series
  260. {
  261. get { return _series; }
  262. }
  263. #endregion
  264. }
  265. }