comparison Applications/Samples/CtPetDoseStructFusion/CtPetDoseStructFusionApplication.cpp @ 540:7428c5dfa5df ct-pet-dose-struct

Initial commit non working app
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 19 Mar 2019 16:29:07 +0100
parents
children
comparison
equal deleted inserted replaced
538:9d124a81c34a 540:7428c5dfa5df
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "CtPetDoseStructFusionApplication.h"
23
24 #if ORTHANC_ENABLE_QT == 1
25 # include "Qt/CtPetDoseStructFusionMainWindow.h"
26 #endif
27
28 #if ORTHANC_ENABLE_WASM == 1
29 # include <Platforms/Wasm/WasmViewport.h>
30 #endif
31
32 namespace CtPetDoseStructFusion
33 {
34
35 void CtPetDoseStructFusionApplication::Initialize(StoneApplicationContext* context,
36 IStatusBar& statusBar,
37 const boost::program_options::variables_map& parameters)
38 {
39 using namespace OrthancStone;
40
41 context_ = context;
42 statusBar_ = &statusBar;
43
44 {// initialize viewports and layout
45 mainLayout_ = new LayoutWidget("main-layout");
46 mainLayout_->SetPadding(10);
47 mainLayout_->SetBackgroundCleared(true);
48 mainLayout_->SetBackgroundColor(0, 0, 0);
49 mainLayout_->SetHorizontal();
50
51 thumbnailsLayout_ = new LayoutWidget("thumbnail-layout");
52 thumbnailsLayout_->SetPadding(10);
53 thumbnailsLayout_->SetBackgroundCleared(true);
54 thumbnailsLayout_->SetBackgroundColor(50, 50, 50);
55 thumbnailsLayout_->SetVertical();
56
57 mainWidget_ = new SliceViewerWidget(IObserver::GetBroker(), "main-viewport");
58 //mainWidget_->RegisterObserver(*this);
59
60 // hierarchy
61 mainLayout_->AddWidget(thumbnailsLayout_);
62 mainLayout_->AddWidget(mainWidget_);
63
64 // sources
65 smartLoader_.reset(new SmartLoader(IObserver::GetBroker(), context->GetOrthancApiClient()));
66 smartLoader_->SetImageQuality(SliceImageQuality_FullPam);
67
68 mainLayout_->SetTransmitMouseOver(true);
69 mainWidgetInteractor_.reset(new MainWidgetInteractor(*this));
70 mainWidget_->SetInteractor(*mainWidgetInteractor_);
71 thumbnailInteractor_.reset(new ThumbnailInteractor(*this));
72 }
73
74 statusBar.SetMessage("Use the key \"s\" to reinitialize the layout");
75 statusBar.SetMessage("Use the key \"n\" to go to next image in the main viewport");
76
77 #if TODO_BGO_CDSF
78 if (parameters.count("studyId") < 1)
79 {
80 LOG(WARNING) << "The study ID is missing, will take the first studyId found in Orthanc";
81 context->GetOrthancApiClient().GetJsonAsync("/studies", new Callable<CtPetDoseStructFusionApplication, OrthancApiClient::JsonResponseReadyMessage>(*this, &CtPetDoseStructFusionApplication::OnStudyListReceived));
82 }
83 else
84 {
85 SelectStudy(parameters["studyId"].as<std::string>());
86 }
87 #endif
88 // TODO_BGO_CDSF
89 }
90
91
92 void CtPetDoseStructFusionApplication::DeclareStartupOptions(boost::program_options::options_description& options)
93 {
94 boost::program_options::options_description generic("Sample options");
95 #if TODO_BGO_CDSF
96 generic.add_options()
97 ("studyId", boost::program_options::value<std::string>(),
98 "Orthanc ID of the study")
99 ;
100
101 options.add(generic);
102 #endif
103 }
104
105 void CtPetDoseStructFusionApplication::OnStudyListReceived(const OrthancApiClient::JsonResponseReadyMessage& message)
106 {
107 const Json::Value& response = message.GetJson();
108
109 if (response.isArray() &&
110 response.size() >= 1)
111 {
112 SelectStudy(response[0].asString());
113 }
114 }
115 void CtPetDoseStructFusionApplication::OnStudyReceived(const OrthancApiClient::JsonResponseReadyMessage& message)
116 {
117 const Json::Value& response = message.GetJson();
118
119 if (response.isObject() && response["Series"].isArray())
120 {
121 for (size_t i=0; i < response["Series"].size(); i++)
122 {
123 context_->GetOrthancApiClient().GetJsonAsync(
124 "/series/" + response["Series"][(int)i].asString(),
125 new Callable<
126 CtPetDoseStructFusionApplication
127 , OrthancApiClient::JsonResponseReadyMessage>(
128 *this,
129 &CtPetDoseStructFusionApplication::OnSeriesReceived
130 )
131 );
132 }
133 }
134 }
135
136 void CtPetDoseStructFusionApplication::OnSeriesReceived(const OrthancApiClient::JsonResponseReadyMessage& message)
137 {
138 const Json::Value& response = message.GetJson();
139
140 if (response.isObject() &&
141 response["Instances"].isArray() &&
142 response["Instances"].size() > 0)
143 {
144 // keep track of all instances IDs
145 const std::string& seriesId = response["ID"].asString();
146 seriesTags_[seriesId] = response;
147 instancesIdsPerSeriesId_[seriesId] = std::vector<std::string>();
148 for (size_t i = 0; i < response["Instances"].size(); i++)
149 {
150 const std::string& instanceId = response["Instances"][static_cast<int>(i)].asString();
151 instancesIdsPerSeriesId_[seriesId].push_back(instanceId);
152 }
153
154 // load the first instance in the thumbnail
155 LoadThumbnailForSeries(seriesId, instancesIdsPerSeriesId_[seriesId][0]);
156
157 // if this is the first thumbnail loaded, load the first instance in the mainWidget
158 if (mainWidget_->GetLayerCount() == 0)
159 {
160 smartLoader_->SetFrameInWidget(*mainWidget_, 0, instancesIdsPerSeriesId_[seriesId][0], 0);
161 }
162 }
163 }
164
165 void CtPetDoseStructFusionApplication::LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId)
166 {
167 LOG(INFO) << "Loading thumbnail for series " << seriesId;
168
169 SliceViewerWidget* thumbnailWidget =
170 new SliceViewerWidget(IObserver::GetBroker(), "thumbnail-series-" + seriesId);
171 thumbnails_.push_back(thumbnailWidget);
172 thumbnailsLayout_->AddWidget(thumbnailWidget);
173
174 thumbnailWidget->RegisterObserverCallback(
175 new Callable<CtPetDoseStructFusionApplication, SliceViewerWidget::GeometryChangedMessage>
176 (*this, &CtPetDoseStructFusionApplication::OnWidgetGeometryChanged));
177
178 smartLoader_->SetFrameInWidget(*thumbnailWidget, 0, instanceId, 0);
179 thumbnailWidget->SetInteractor(*thumbnailInteractor_);
180 }
181
182 void CtPetDoseStructFusionApplication::SelectStudy(const std::string& studyId)
183 {
184 context_->GetOrthancApiClient().GetJsonAsync("/studies/" + studyId, new Callable<CtPetDoseStructFusionApplication, OrthancApiClient::JsonResponseReadyMessage>(*this, &CtPetDoseStructFusionApplication::OnStudyReceived));
185 }
186
187 void CtPetDoseStructFusionApplication::OnWidgetGeometryChanged(const SliceViewerWidget::GeometryChangedMessage& message)
188 {
189 // TODO: The "const_cast" could probably be replaced by "mainWidget_"
190 const_cast<SliceViewerWidget&>(message.GetOrigin()).FitContent();
191 }
192
193 void CtPetDoseStructFusionApplication::SelectSeriesInMainViewport(const std::string& seriesId)
194 {
195 smartLoader_->SetFrameInWidget(*mainWidget_, 0, instancesIdsPerSeriesId_[seriesId][0], 0);
196 }
197
198 bool CtPetDoseStructFusionApplication::Handle(const StoneSampleCommands::SelectTool& value) ORTHANC_OVERRIDE
199 {
200 currentTool_ = value.tool;
201 return true;
202 }
203
204 bool CtPetDoseStructFusionApplication::Handle(const StoneSampleCommands::Action& value) ORTHANC_OVERRIDE
205 {
206 switch (value.type)
207 {
208 case ActionType_Invert:
209 // TODO
210 break;
211 case ActionType_UndoCrop:
212 // TODO
213 break;
214 case ActionType_Rotate:
215 // TODO
216 break;
217 default:
218 throw std::runtime_error("Action type not supported");
219 }
220 return true;
221 }
222
223 #if ORTHANC_ENABLE_QT==1
224 QStoneMainWindow* CtPetDoseStructFusionApplication::CreateQtMainWindow()
225 {
226 return new CtPetDoseStructFusionMainWindow(dynamic_cast<OrthancStone::NativeStoneApplicationContext&>(*context_), *this);
227 }
228 #endif
229
230 #if ORTHANC_ENABLE_WASM==1
231 void CtPetDoseStructFusionApplication::InitializeWasm() {
232
233 AttachWidgetToWasmViewport("canvasThumbnails", thumbnailsLayout_);
234 AttachWidgetToWasmViewport("canvasMain", mainWidget_);
235 }
236 #endif
237
238
239 }