Diagram showing the OpenREM system componentsΒΆ

digraph {
   node [fixedsize=true width=2.0 height=0.75 fontsize=10 margin="0.0,0.0"];

   // Define the things on the server
   subgraph cluster_server {

      label="OpenREM server";
      tooltip="The server";
      fontname="Helvetica-bold";
      fontsize=16;
      style=filled;
      color=lightgrey;
      node [style=filled color=white];

      // Define the nodes for the data storage, display and retrieval
      webserver [label="Apache\nweb server" fontname="Helvetica" tooltip="Serve web pages to the user" shape="box"];
      python_django [label="OpenREM\nDjango app" fontname="Helvetica" tooltip="Python web framework" shape="box"];
      database [label="PostgreSQL\ndatabase" fontname="Helvetica" tooltip="Relational database management system" shape="parallelogram"];
      rabbitmq [label="RabbitMQ\nmessage broker" fontname="Helvetica" tooltip="Message broker" shape="box"];
      celery [label="Celery\ntask queue" fontname="Helvetica" tooltip="Asynchronous task queue" shape="hexagon"];
      skin_dose_map_data [label="Skin dose map\ndata calculation,\nstorage, retrieval" fontname="Helvetica" tooltip="Calculate, store and retrieve skin dose map data" shape="parallelogram"];
      server_media_folder [label="Server file storage\n(Media Home folder)" fontname="Helvetica" tooltip="File storage on the server" shape="parallelogram"];
      data_export [label="Data export to\nlocal file system" fontname="Helvetica" tooltip="Files are made available to the user via a web page URL" shape="box"];

      // Define the links between the data storage, display and retrieval
      webserver -> python_django [dir=both];
      python_django -> database [dir=both label="via psycopg2\nPython adapter" fontsize=8 fontname="Courier"];
      python_django -> rabbitmq;
      rabbitmq -> celery;
      celery -> skin_dose_map_data;
      celery -> data_export;
      skin_dose_map_data -> server_media_folder [dir=both];
      skin_dose_map_data -> python_django [style=dotted dir=both];
      data_export -> server_media_folder;
      data_export -> python_django [style=dotted dir=both];

      // Define the nodes for the DICOM store, database population and skin dose map calculation
      conquest [label="DICOM StoreSCP\n(Conquest)" fontname="Helvetica" tooltip="Conquest, acting as a DICOM storage SCP" shape="box"];
      conquest_script [shape=diamond label="Does the\nobject contain\nuseful data?" fontname="Helvetica" tooltip="Process the rules in dicom.ini"];
      populate_database [label="Extract information from\nthe DICOM object to the\nOpenREM database" fontname="Helvetica", tooltip="Extract data using OpenREM's python scripts" shape="box"];
      delete_object [label="Delete the DICOM object\nfrom the Conquest store" fontname="Helvetica" tooltip="Delete the DICOM object from the local store SCP" shape="box"];
      calc_skin_dose_map [shape=diamond label="Calculate\nskin dose\nmap?" fontname="Helvetica" tooltip="Calculate the skin dose map?"];

      // Define the links between the DICOM store, database population and skin dose map calculation
      conquest_script -> populate_database [label="Yes" fontcolor=darkgreen fontsize=8 fontname="Courier"];
      populate_database -> delete_object;
      conquest_script -> delete_object [label="No" fontcolor=red fontsize=8 fontname="Courier"];
      conquest -> conquest_script;
      populate_database -> calc_skin_dose_map;

      // Define the links between the two groups
      python_django -> populate_database [dir=back]
      calc_skin_dose_map -> celery [style=dotted label="Yes" fontcolor=darkgreen fontsize=8 fontname="Courier"]

      // Force certain nodes to be on the same level so that the diagram looks good (hopefully)
      {rank=same; webserver conquest};
      {rank=same; python_django populate_database delete_object}
   }

   // Define the web browser, modality and pacs nodes
   web_browser [label="Client\nweb browser" fontname="Helvetica" tooltip="The user's web browser" shape="box" style=rounded];
   modality [label="X-ray imaging\nmodality" fontname="Helvetica" tooltip="Data send from an x-ray imaging modality" shape="parallelogram"];
   pacs [label="PACS" fontname="Helvetica" tooltip="A Picture Archiving and Communication System" shape="parallelogram"];

   // Define the links that the browser, modality and pacs have
   web_browser -> webserver [dir=both label="via user-requests\land Ajax\l" fontsize=8 fontname="Courier" tooltip="Ajax used to retrieve chart data"];
   modality -> conquest [label="via modality\lconfiguration\l" fontsize=8 fontname="Courier"];
   pacs -> conquest [label="via OpenREM\lquery-retrieve\l" fontsize=8 fontname="Courier"];

   // Force the web browser, modality and pacs to be on the same level
   {rank=same; web_browser modality pacs};
}