IMHOTEP Framework
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Pages
Patient.cs
1 using UnityEngine;
2 using System;
3 using System.Collections;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Text;
7 using System.IO;
8 using itk.simple;
9 using LitJson;
10 using UI;
11 using System.ComponentModel;
12 
13 public class Patient : PatientMeta
14 {
15  static private Patient loadedPatient = null;
16 
17  private List<AdditionalInformation> additionalInformation = new List<AdditionalInformation> ();
18  private List<string> additionalInformationTabs = new List<string> ();
19  private List<View> mViews = new List<View> ();
20  private List<AnnotationJson> rawAnnotation = new List<AnnotationJson> ();
21  private List<GameObject> mAnnotations = new List<GameObject> ();
22 
23  public class AdditionalInformation
24  {
25  public string name { get; set; }
26  public string type { get; set; }
27  public string content { get; set; } //TODO save path, not content of the file
28  public string tabName { get; set; }
29  }
30 
31  public Patient( PatientMeta meta ) : base(meta)
32  {
33  PatientEventSystem.stopListening (PatientEventSystem.Event.PATIENT_FinishedLoading, finishedLoading); // if we were listening already, stop
34  PatientEventSystem.startListening (PatientEventSystem.Event.PATIENT_FinishedLoading, finishedLoading);
35  PatientEventSystem.startListening (PatientEventSystem.Event.PATIENT_Closed, closePatient);
36 
37  ThreadUtil t = new ThreadUtil(this.PatientLoaderWorker, this.PatientLoaderCallback);
38  t.Run();
39  }
40  ~Patient()
41  {
42  stopListeningToEvents ();
43  }
44 
45  private void stopListeningToEvents()
46  {
47  PatientEventSystem.stopListening (PatientEventSystem.Event.PATIENT_FinishedLoading, finishedLoading);
48  }
49 
50  private string rewritePathInHTML(string content, string filePath)
51  {
52  //
53  string folderHTMLSources = "";
54  string[] substrings = filePath.Split('/');
55  for (int i = 0; i < substrings.Length - 1; i++)
56  {
57  folderHTMLSources += substrings[i];
58  }
59 
60  //Rewrite src and href in HTML, because relative paths are wrong
61  string c = content;
62  c = c.Replace("src=\".", "src=\"./" + path + "/" + folderHTMLSources);
63  c = c.Replace("href=\".", "href=\"./" + path + "/" + folderHTMLSources);
64  return c;
65  }
66 
67 
68  public static Patient getLoadedPatient()
69  {
70  return loadedPatient;
71  }
72 
73  public void save()
74  {
75  saveViews ();
76  saveAnnotation();
77  }
78 
79  public static void close()
80  {
81  if (loadedPatient != null)
82  loadedPatient.stopListeningToEvents ();
83  loadedPatient = null;
84  }
85 
86  public List<string> getAdditionalInfoTabs()
87  {
88  return additionalInformationTabs;
89  }
90  public List<AdditionalInformation> getAdditionalInfo()
91  {
92  return additionalInformation;
93 
94  /*
95  string result = "";
96  foreach (AdditionalInformation info in additionalInformation) {
97  // Add all info for this tab to the string:
98  if (info.tabName == tabName) {
99  result += "<b>" + info.name + "</b>" + "\n\n";
100  result += info.content + "\n\n";
101  }
102  }
103  return result; */
104  }
105 
106  private string bold( string input )
107  {
108  return "<b>" + input + "</b>";
109  }
110 
112  // Views:
113 
114  public int getViewCount()
115  {
116  return mViews.Count;
117  }
118  public int insertView( View newView, int index )
119  {
120  index = Mathf.Min (index, mViews.Count);
121  mViews.Insert (index, newView);
122  return index;
123  }
124  public View getView( int index )
125  {
126  if ( index >= 0 && mViews.Count > index) {
127  return mViews [index];
128  } else {
129  return null;
130  }
131  }
132  public void deleteView( int index )
133  {
134  if (index >= 0 && mViews.Count > index) {
135  mViews.RemoveAt (index);
136  }
137  }
138 
139  private void readViews()
140  {
141  // Find any views in a seperate view file, if given:
142  string viewsFile = Path.Combine (base.path, "views.json"); // TODO: Read from base path?
143  mViews.Clear ();
144  //Debug.Log ("Loading Views: " + viewsFile);
145  if (File.Exists (viewsFile)) {
146  try {
147  // Read the file
148  string line;
149  System.IO.StreamReader file = new System.IO.StreamReader (viewsFile);
150  while ((line = file.ReadLine ()) != null) {
151  ViewJson vj = JsonMapper.ToObject<ViewJson> (line);
152  View view = new View (vj);
153  mViews.Add (view);
154  }
155  file.Close ();
156  } catch {
157  mViews.Clear ();
158  }
159  }
160  Debug.Log ("Loaded: " + mViews.Count + " views.");
161  }
162 
163  public void saveViews()
164  {
165  Patient p = Patient.getLoadedPatient();
166  string path = p.path + "/views.json";
167 
168  //Create file if it not exists
169  if (!File.Exists(path))
170  {
171  using (StreamWriter outputFile = new StreamWriter(path,true))
172  {
173  outputFile.Close();
174  }
175  }
176 
177  //Write annotations in file
178  using (StreamWriter outputFile = new StreamWriter(path))
179  {
180  foreach(View view in mViews)
181  {
182  ViewJson vj = new ViewJson(view);
183  outputFile.WriteLine(JsonMapper.ToJson(vj));
184  }
185  outputFile.Close();
186  }
187  return;
188  }
189 
191  // UI:
192 
193  public void setupDefaultWidgets()
194  {
195  // TODO: Get info about default UI widgets from patient's json:
196 
197  Widget w = UI.Core.instance.getWidgetByName ("ViewControl");
198  if (w)
199  w.gameObject.SetActive (true);
200 
201  w = UI.Core.instance.getWidgetByName ("PatientBriefing");
202  if (w)
203  w.gameObject.SetActive (true);
204 
205  w = UI.Core.instance.getWidgetByName ("DICOMViewer");
206  if (w)
207  w.gameObject.SetActive (true);
208  }
209 
210 
211 
212 
213  private void PatientLoaderWorker(object sender, DoWorkEventArgs e)
214  {
215  string metaFile = Path.Combine(base.path, "meta.json");
216  string raw = File.ReadAllText(metaFile);
217  JsonData data;
218  try
219  {
220  data = JsonMapper.ToObject(raw);
221  }
222  catch
223  {
224  throw new System.Exception("Cannot parse meta.json. Invalid syntax?");
225  }
226 
227  if (data.Keys.Contains("additional information"))
228  {
229  JsonData infoArray = data["additional information"];
230 
231  // Set up default tab:
232  additionalInformationTabs.Add("General");
233  string c = "";
234  c += bold("Patient Name: ") + name + "\n";
235  c += bold("Date of Birth: ") + birthDate + "\n";
236  c += bold("Date of Operation: ") + operationDate + "\n";
237  AdditionalInformation info = new AdditionalInformation
238  {
239  name = "Patient Information",
240  type = "Plaintext",
241  content = c,
242  tabName = "General"
243  };
244  additionalInformation.Add(info);
245 
246  // Find other information in files (which are given in meta.json) and add them to the tabs:
247  for (int i = 0; i < infoArray.Count; i++)
248  {
249  JsonData entry = infoArray[i];
250  if (entry.Keys.Contains("Name") && entry.Keys.Contains("File"))
251  { //TODO use JsonMapper.ToObject to load this
252 
253  if (System.IO.File.Exists(base.path + "/" + entry["File"]))
254  {
255  string content = System.IO.File.ReadAllText(base.path + "/" + entry["File"]);
256  string title = entry["Name"].ToString();
257  string type = "plainText";
258  if (entry.Keys.Contains("Type"))
259  type = entry["Type"].ToString();
260  string tabName = "General";
261  if (entry.Keys.Contains("Tab"))
262  {
263  tabName = entry["Tab"].ToString();
264  }
265  if (name.Length > 0 && content.Length > 0)
266  {
267  info = new AdditionalInformation
268  {
269  name = title,
270  type = type,
271  content = content,
272  tabName = tabName
273  };
274  if (info.type == "HTML")
275  {
276  info.content = rewritePathInHTML(info.content, entry["File"].ToString());
277 
278  }
279  additionalInformation.Add(info);
280  if (!additionalInformationTabs.Contains(tabName))
281  {
282  additionalInformationTabs.Add(tabName);
283  }
284  }
285  }
286  }
287  }
288  }
289 
290  readViews();
291  loadAnnotationFromFile ();
292  }
293 
294  private void PatientLoaderCallback(object sender, RunWorkerCompletedEventArgs e)
295  {
296  //BackgroundWorker worker = sender as BackgroundWorker;
297  if (e.Cancelled)
298  {
299  Debug.Log("[Patient.cs] Patient Loading cancelled"); //Not implemented in worker yet
300  }
301  else if (e.Error != null)
302  {
303  Debug.LogError("[Patient.cs] Error while loading the patient");
304  }
305  else
306  {
307  loadedPatient = this;
308 
309  // Let other widgets know the patient information is now available:
310  PatientEventSystem.triggerEvent(PatientEventSystem.Event.PATIENT_Loaded, this);
311  }
312  return;
313  }
314 
315 
317  // Annotations:
318 
319  public void updateAnnotationList( List<GameObject> list )
320  {
321  mAnnotations = list;
322  }
323 
324  //Load all annotations out of File in List
325  private void loadAnnotationFromFile (object obj = null)
326  {
327 
328 
329 
330  //Clear Screen
331  //clearAll ();
332 
333  //get Annotation.json
334 
335  string path = this.path + "/annotation.json"; //TODO read from meta.json??
336 
337  if (!File.Exists (path)) {
338  return;
339  }
340 
341  List<AnnotationJson> apjList = new List<AnnotationJson> ();
342  // Read the file
343  string line;
344  System.IO.StreamReader file = new System.IO.StreamReader (path);
345  while ((line = file.ReadLine ()) != null) {
346  AnnotationJson apj = JsonUtility.FromJson<AnnotationJson> (line);
347  apjList.Add (apj);
348  }
349  file.Close ();
350 
351  //List of Json Objects -> AnnotationList
352  rawAnnotation = apjList;
353  }
354 
355  public void createAnnotations() {
356  foreach(AnnotationJson aJson in rawAnnotation) {
357  AnnotationControl.instance.createAnnotation (aJson);
358  }
359  AnnotationControl.instance.updatePatientAnnotationList ();
360  AnnotationControl.instance.clearAll ();
361  }
362 
363 
364  //Saves all annotations in a file
365  public void saveAnnotation ()
366  {
367 
368  if (loadedPatient == null) {
369  return;
370  }
371 
372  string path = loadedPatient.path + "/annotation.json";
373 
374  //Create file if it not exists
375  if (!File.Exists (path)) {
376  using (StreamWriter outputFile = new StreamWriter (path, true)) {
377  outputFile.Close ();
378  }
379  }
380 
381  //Write annotations in file
382  using (StreamWriter outputFile = new StreamWriter (path)) {
383  foreach (GameObject apListEntry in mAnnotations) {
384  GameObject ap = apListEntry.GetComponent<AnnotationListEntry> ().getAnnotation ();
385  if (ap != null) {
386  AnnotationJson apj = new AnnotationJson ();
387  apj.type = ap.GetComponent<Annotation> ().myType;
388  apj.Text = ap.GetComponent<Annotation> ().getLabelText ();
389  apj.ColorR = ap.GetComponent<Annotation> ().getColor ().r;
390  apj.ColorG = ap.GetComponent<Annotation> ().getColor ().g;
391  apj.ColorB = ap.GetComponent<Annotation> ().getColor ().b;
392  apj.ScaleX = ap.GetComponent<Annotation> ().getMeshScale ().x;
393  apj.ScaleY = ap.GetComponent<Annotation> ().getMeshScale ().y;
394  apj.ScaleZ = ap.GetComponent<Annotation> ().getMeshScale ().z;
395  apj.PositionX = ap.transform.localPosition.x;
396  apj.PositionY = ap.transform.localPosition.y;
397  apj.PositionZ = ap.transform.localPosition.z;
398 
399  apj.RotationW = ap.transform.localRotation.w;
400  apj.RotationX = ap.transform.localRotation.x;
401  apj.RotationY = ap.transform.localRotation.y;
402  apj.RotationZ = ap.transform.localRotation.z;
403 
404 
405  apj.MeshRotationW = ap.GetComponent<Annotation> ().myAnnotationMesh.transform.localRotation.w;
406  apj.MeshRotationX = ap.GetComponent<Annotation> ().myAnnotationMesh.transform.localRotation.x;
407  apj.MeshRotationY = ap.GetComponent<Annotation> ().myAnnotationMesh.transform.localRotation.y;
408  apj.MeshRotationZ = ap.GetComponent<Annotation> ().myAnnotationMesh.transform.localRotation.z;
409 
410 
411  apj.Creator = ap.GetComponent<Annotation> ().creator;
412  apj.CreationDate = ap.GetComponent<Annotation> ().creationDate;
413  outputFile.WriteLine (JsonUtility.ToJson (apj));
414  }
415  }
416  outputFile.Close ();
417  }
418  return;
419  }
420 
422  // Misc:
423 
424  public void finishedLoading(object obj = null)
425  {
426  //Annotation load
427  createAnnotations();
428 
429  setupDefaultWidgets();
430  NotificationControl.instance.createNotification ("Patient loaded.", new TimeSpan (0, 0, 5));
431  }
432 
433  //Called if the patient is closed
434  public void closePatient (object obj = null)
435  {
436  AnnotationControl.instance.deleteAllAnnotations ();
437  AnnotationControl.instance.resetLayers ();
438  PatientEventSystem.stopListening (PatientEventSystem.Event.PATIENT_Closed, closePatient);
439  }
440 }
Definition: View.cs:37
Definition: View.cs:9