selxRegistrationItkv4Test.cxx 23.1 KB
Newer Older
Floris Berendsen's avatar
Floris Berendsen committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*=========================================================================
 *
 *  Copyright Leiden University Medical Center, Erasmus University Medical 
 *  Center and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

20
#include "selxSuperElastixFilter.h"
21
22
23
24
25
26
27
28
29

#include "TransformComponent1.h"
#include "MetricComponent1.h"
#include "GDOptimizer3rdPartyComponent.h"
#include "GDOptimizer4thPartyComponent.h"
#include "SSDMetric3rdPartyComponent.h"
#include "SSDMetric4thPartyComponent.h"

#include "selxItkSmoothingRecursiveGaussianImageFilterComponent.h"
30
#include "selxDisplacementFieldItkImageFilterSink.h"
31
#include "selxItkImageSource.h"
32
#include "selxItkImageSink.h"
33
34

#include "selxItkImageRegistrationMethodv4Component.h"
35
#include "selxItkANTSNeighborhoodCorrelationImageToImageMetricv4.h"
36
#include "selxItkMeanSquaresImageToImageMetricv4.h"
37
#include "selxItkGradientDescentOptimizerv4.h"
38
#include "selxItkAffineTransform.h"
39
#include "selxItkGaussianExponentialDiffeomorphicTransform.h"
40
#include "selxItkTransformDisplacementFilter.h"
41
#include "selxItkResampleFilter.h"
42
43
44
#include "selxItkImageSourceFixed.h"
#include "selxItkImageSourceMoving.h"

Floris Berendsen's avatar
Floris Berendsen committed
45
46
47
48
49
50
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

#include "itkMeshFileReader.h"
#include "itkMeshFileWriter.h" 

51
52
#include "DefaultComponents.h"

53
#include "selxDataManager.h"
54
55
56
57
58
59
60
61
62
63
#include "gtest/gtest.h"

namespace selx {

class RegistrationItkv4Test : public ::testing::Test {
public:
  typedef Blueprint::Pointer                BlueprintPointerType;
  typedef Blueprint::ConstPointer           BlueprintConstPointerType;
  typedef Blueprint::ParameterMapType       ParameterMapType;
  typedef Blueprint::ParameterValueType     ParameterValueType;
64
  typedef DataManager DataManagerType;
65
66
  
     /** register all example components */
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  typedef TypeList < TransformComponent1,
    MetricComponent1,
    GDOptimizer3rdPartyComponent,
    GDOptimizer4thPartyComponent,
    SSDMetric3rdPartyComponent,
    SSDMetric4thPartyComponent,
    DisplacementFieldItkImageFilterSinkComponent<3, double>,
    DisplacementFieldItkImageFilterSinkComponent<2, float>,
    ItkImageSinkComponent<3, double>,
    ItkImageSinkComponent<2, float>,
    ItkImageSourceFixedComponent<2, float>,
    ItkImageSourceMovingComponent<2, float>,
    ItkImageSourceFixedComponent<3, double>,
    ItkImageSourceMovingComponent<3, double>,
    ItkSmoothingRecursiveGaussianImageFilterComponent<3, double>,
    ItkSmoothingRecursiveGaussianImageFilterComponent<2, double>,
    ItkSmoothingRecursiveGaussianImageFilterComponent<3, float>,
    ItkSmoothingRecursiveGaussianImageFilterComponent<2, float>,
    ItkImageRegistrationMethodv4Component<3, double>,
    ItkImageRegistrationMethodv4Component<2, float>,
    ItkANTSNeighborhoodCorrelationImageToImageMetricv4Component<3, double>,
    ItkMeanSquaresImageToImageMetricv4Component<3, double>,
    ItkANTSNeighborhoodCorrelationImageToImageMetricv4Component<2, float>,
90
    ItkMeanSquaresImageToImageMetricv4Component < 2, float >,
91
    ItkGradientDescentOptimizerv4Component<double>,
92
    ItkAffineTransformComponent<double,3>,
93
    ItkGaussianExponentialDiffeomorphicTransformComponent<double, 3>,
94
    ItkTransformDisplacementFilterComponent<2, float, double >,
95
96
97
    ItkTransformDisplacementFilterComponent<3, double, double >,
    ItkResampleFilterComponent<2, float, double >,
    ItkResampleFilterComponent<3, double, double >> RegisterComponents;
98
99
	
  typedef SuperElastixFilter<RegisterComponents>          SuperElastixFilterType;
100
101
102
103
104
105
106
107

  typedef itk::Image<float, 2> Image2DType;
  typedef itk::ImageFileReader<Image2DType> ImageReader2DType;
  typedef itk::ImageFileWriter<Image2DType> ImageWriter2DType;

  typedef itk::Image<double, 3> Image3DType;
  typedef itk::ImageFileReader<Image3DType> ImageReader3DType;
  typedef itk::ImageFileWriter<Image3DType> ImageWriter3DType;
108

109
110
  typedef itk::Image<itk::Vector<double,3>, 3> DisplacementImage3DType;
  typedef itk::ImageFileWriter<DisplacementImage3DType> DisplacementImageWriter3DType;
111
112

  virtual void SetUp() {
113
 
114

115
116
117
118
119
120
121
  }

  virtual void TearDown() {
    itk::ObjectFactoryBase::UnRegisterAllFactories();
  }

  BlueprintPointerType blueprint;
Floris Berendsen's avatar
Floris Berendsen committed
122
  
123

124
125
};

126
127
128
129
// These test are disabled, since may not want to check each component with this much boilerplate code. 
// We should consider moving functional tests outside the unit tests
// Anyway, the Blueprint configuration needs to be updated
TEST_F(RegistrationItkv4Test, DISABLED_3DImagesOnly) 
130
{
131
132
  /** make example blueprint configuration */
  blueprint = Blueprint::New();
133

134
135
  ParameterMapType component0Parameters;
  component0Parameters["NameOfClass"] = { "ItkImageRegistrationMethodv4Component" };
136
  component0Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
137
  blueprint->AddComponent("RegistrationMethod", component0Parameters);
138

139
140
  ParameterMapType component1Parameters;
  component1Parameters["NameOfClass"] = { "ItkImageSourceFixedComponent" };
141
  component1Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
142
  blueprint->AddComponent("FixedImageSource", component1Parameters);
143

144
145
  ParameterMapType component2Parameters;
  component2Parameters["NameOfClass"] = { "ItkImageSourceMovingComponent" };
146
  component2Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
147
  blueprint->AddComponent("MovingImageSource", component2Parameters);
148

149
  ParameterMapType component3Parameters;
150
  component3Parameters["NameOfClass"] = { "ItkImageSinkComponent" };
151
  component3Parameters["Dimensionality"] = { "3" }; // should be derived from the outputs
152
  blueprint->AddComponent("ResultImageSink", component3Parameters);
153
154


155
  ParameterMapType connection1Parameters;
156
  connection1Parameters["NameOfInterface"] = { "itkImageFixedInterface" };
157
  blueprint->AddConnection("FixedImageSource", "RegistrationMethod", connection1Parameters);
158

159
  ParameterMapType connection2Parameters;
160
  connection2Parameters["NameOfInterface"] = { "itkImageMovingInterface" };
161
  blueprint->AddConnection("MovingImageSource", "RegistrationMethod", connection2Parameters);
162

163
  ParameterMapType connection3Parameters;
164
  connection3Parameters["NameOfInterface"] = { "itkImageInterface" };
165
  blueprint->AddConnection("RegistrationMethod", "ResultImageSink", connection3Parameters);
166

167
168
169
170
171
  // Instantiate SuperElastix
  SuperElastixFilterType::Pointer superElastixFilter;
  EXPECT_NO_THROW(superElastixFilter = SuperElastixFilterType::New());

  // Data manager provides the paths to the input and output data for unit tests
172
173
  DataManagerType::Pointer dataManager = DataManagerType::New();

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  // Set up the readers and writers
  ImageReader3DType::Pointer fixedImageReader = ImageReader3DType::New();
  fixedImageReader->SetFileName(dataManager->GetInputFile("sphereA3d.mhd"));

  ImageReader3DType::Pointer movingImageReader = ImageReader3DType::New();
  movingImageReader->SetFileName(dataManager->GetInputFile("sphereB3d.mhd"));

  ImageWriter3DType::Pointer resultImageWriter = ImageWriter3DType::New();
  resultImageWriter->SetFileName(dataManager->GetOutputFile("RegistrationItkv4Test_ImagesOnly.mhd"));

  // Connect SuperElastix in an itk pipeline
  superElastixFilter->SetInput("FixedImageSource", fixedImageReader->GetOutput());
  superElastixFilter->SetInput("MovingImageSource", movingImageReader->GetOutput());
  resultImageWriter->SetInput(superElastixFilter->GetOutput<Image3DType>("ResultImageSink"));

  EXPECT_NO_THROW(superElastixFilter->SetBlueprint(blueprint));

  //Optional Update call
  //superElastixFilter->Update();

  // Update call on the writers triggers SuperElastix to configure and execute
  EXPECT_NO_THROW(resultImageWriter->Update());
    
197
198
}

199
200
201
202
// These test are disabled, since may not want to check each component with this much boilerplate code. 
// We should consider moving functional tests outside the unit tests
// Anyway, the Blueprint configuration needs to be updated
TEST_F(RegistrationItkv4Test, DISABLED_3DANTSCCMetric)
203
204
205
206
207
208
{
  /** make example blueprint configuration */
  blueprint = Blueprint::New();

  ParameterMapType component0Parameters;
  component0Parameters["NameOfClass"] = { "ItkImageRegistrationMethodv4Component" };
209
  component0Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
210
  blueprint->AddComponent("RegistrationMethod", component0Parameters);
211
212
213

  ParameterMapType component1Parameters;
  component1Parameters["NameOfClass"] = { "ItkImageSourceFixedComponent" };
214
  component1Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
215
  blueprint->AddComponent("FixedImageSource", component1Parameters);
216

217
218
  ParameterMapType component2Parameters;
  component2Parameters["NameOfClass"] = { "ItkImageSourceMovingComponent" };
219
  component2Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
220
  blueprint->AddComponent("MovingImageSource", component2Parameters);
221
222

  ParameterMapType component3Parameters;
223
  component3Parameters["NameOfClass"] = { "ItkImageSinkComponent" };
224
  component3Parameters["Dimensionality"] = { "3" }; // should be derived from the outputs
225
  blueprint->AddComponent("ResultImageSink", component3Parameters);
226
227
228

  ParameterMapType component4Parameters;
  component4Parameters["NameOfClass"] = { "ItkANTSNeighborhoodCorrelationImageToImageMetricv4Component" };
229
  component4Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
230
  blueprint->AddComponent("Metric", component4Parameters);
231

232
233
  ParameterMapType component5Parameters;
  component5Parameters["NameOfClass"] = { "ItkGradientDescentOptimizerv4Component" };
234
  component5Parameters["NumberOfIterations"] = { "1" };
235
  blueprint->AddComponent("Optimizer", component5Parameters);
236
237

  ParameterMapType connection1Parameters;
238
  connection1Parameters["NameOfInterface"] = { "itkImageFixedInterface" };
239
  blueprint->AddConnection("FixedImageSource", "RegistrationMethod", connection1Parameters);
240
241

  ParameterMapType connection2Parameters;
242
  connection2Parameters["NameOfInterface"] = { "itkImageMovingInterface" };
243
  blueprint->AddConnection("MovingImageSource", "RegistrationMethod", connection2Parameters);
244
245

  ParameterMapType connection3Parameters;
246
  connection3Parameters["NameOfInterface"] = { "itkImageInterface" };
247
248
  blueprint->AddConnection("RegistrationMethod", "ResultImageSink", connection3Parameters);
  
249
250
  ParameterMapType connection4Parameters;
  connection4Parameters["NameOfInterface"] = { "itkMetricv4Interface" };
251
  blueprint->AddConnection("Metric", "RegistrationMethod", connection4Parameters);
252

253
254
255
256
257
  ParameterMapType connection5Parameters;
  connection5Parameters["NameOfInterface"] = { "itkOptimizerv4Interface" };
  blueprint->AddConnection("Optimizer", "RegistrationMethod", connection5Parameters);


258
259
260
261
262
  // Instantiate SuperElastix
  SuperElastixFilterType::Pointer superElastixFilter;
  EXPECT_NO_THROW(superElastixFilter = SuperElastixFilterType::New());

  // Data manager provides the paths to the input and output data for unit tests
263
  DataManagerType::Pointer dataManager = DataManagerType::New();
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

  // Set up the readers and writers
  ImageReader3DType::Pointer fixedImageReader = ImageReader3DType::New();
  fixedImageReader->SetFileName(dataManager->GetInputFile("sphereA3d.mhd"));

  ImageReader3DType::Pointer movingImageReader = ImageReader3DType::New();
  movingImageReader->SetFileName(dataManager->GetInputFile("sphereB3d.mhd"));

  ImageWriter3DType::Pointer resultImageWriter = ImageWriter3DType::New();
  resultImageWriter->SetFileName(dataManager->GetOutputFile("RegistrationItkv4Test_WithANTSCCMetric.mhd"));

  // Connect SuperElastix in an itk pipeline
  superElastixFilter->SetInput("FixedImageSource", fixedImageReader->GetOutput());
  superElastixFilter->SetInput("MovingImageSource", movingImageReader->GetOutput());
  resultImageWriter->SetInput(superElastixFilter->GetOutput<Image3DType>("ResultImageSink"));

  EXPECT_NO_THROW(superElastixFilter->SetBlueprint(blueprint));

  //Optional Update call
  //superElastixFilter->Update();

  // Update call on the writers triggers SuperElastix to configure and execute
  EXPECT_NO_THROW(resultImageWriter->Update());
287
}
288
289
290
291
292

// These test are disabled, since may not want to check each component with this much boilerplate code. 
// We should consider moving functional tests outside the unit tests
// Anyway, the Blueprint configuration needs to be updated
TEST_F(RegistrationItkv4Test, DISABLED_3DMeanSquaresMetric)
293
294
295
296
297
298
{
  /** make example blueprint configuration */
  blueprint = Blueprint::New();

  ParameterMapType component0Parameters;
  component0Parameters["NameOfClass"] = { "ItkImageRegistrationMethodv4Component" };
299
  component0Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
300
  blueprint->AddComponent("RegistrationMethod", component0Parameters);
301
302
303

  ParameterMapType component1Parameters;
  component1Parameters["NameOfClass"] = { "ItkImageSourceFixedComponent" };
304
  component1Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
305
  blueprint->AddComponent("FixedImageSource", component1Parameters);
306
307
308

  ParameterMapType component2Parameters;
  component2Parameters["NameOfClass"] = { "ItkImageSourceMovingComponent" };
309
  component2Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
310
  blueprint->AddComponent("MovingImageSource", component2Parameters);
311
312

  ParameterMapType component3Parameters;
313
  component3Parameters["NameOfClass"] = { "ItkImageSinkComponent" };
314
  component3Parameters["Dimensionality"] = { "3" }; // should be derived from the outputs
315
  blueprint->AddComponent("ResultImageSink", component3Parameters);
316
317
318

  ParameterMapType component4Parameters;
  component4Parameters["NameOfClass"] = { "ItkMeanSquaresImageToImageMetricv4Component" };
319
  component4Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
320
  blueprint->AddComponent("Metric", component4Parameters);
321

322
323
324
325
  ParameterMapType component5Parameters;
  component5Parameters["NameOfClass"] = { "ItkGradientDescentOptimizerv4Component" };
  component5Parameters["NumberOfIterations"] = { "1" };
  blueprint->AddComponent("Optimizer", component5Parameters);
326
327

  ParameterMapType connection1Parameters;
328
  connection1Parameters["NameOfInterface"] = { "itkImageFixedInterface" };
329
  blueprint->AddConnection("FixedImageSource", "RegistrationMethod", connection1Parameters);
330
331

  ParameterMapType connection2Parameters;
332
  connection2Parameters["NameOfInterface"] = { "itkImageMovingInterface" };
333
  blueprint->AddConnection("MovingImageSource", "RegistrationMethod", connection2Parameters);
334
335

  ParameterMapType connection3Parameters;
336
  connection3Parameters["NameOfInterface"] = { "itkImageInterface" };
337
  blueprint->AddConnection("RegistrationMethod", "ResultImageSink", connection3Parameters);
338
339
340

  ParameterMapType connection4Parameters;
  connection4Parameters["NameOfInterface"] = { "itkMetricv4Interface" };
341
  blueprint->AddConnection("Metric", "RegistrationMethod", connection4Parameters);
342

343
344
345
346
  ParameterMapType connection5Parameters;
  connection5Parameters["NameOfInterface"] = { "itkOptimizerv4Interface" };
  blueprint->AddConnection("Optimizer", "RegistrationMethod", connection5Parameters);

347
348
349
350
351
  // Instantiate SuperElastix
  SuperElastixFilterType::Pointer superElastixFilter;
  EXPECT_NO_THROW(superElastixFilter = SuperElastixFilterType::New());

  // Data manager provides the paths to the input and output data for unit tests
352
  DataManagerType::Pointer dataManager = DataManagerType::New();
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

  // Set up the readers and writers
  ImageReader3DType::Pointer fixedImageReader = ImageReader3DType::New();
  fixedImageReader->SetFileName(dataManager->GetInputFile("sphereA3d.mhd"));

  ImageReader3DType::Pointer movingImageReader = ImageReader3DType::New();
  movingImageReader->SetFileName(dataManager->GetInputFile("sphereB3d.mhd"));

  ImageWriter3DType::Pointer resultImageWriter = ImageWriter3DType::New();
  resultImageWriter->SetFileName(dataManager->GetOutputFile("RegistrationItkv4Test_WithMeanSquaresMetric.mhd"));

  // Connect SuperElastix in an itk pipeline
  superElastixFilter->SetInput("FixedImageSource", fixedImageReader->GetOutput());
  superElastixFilter->SetInput("MovingImageSource", movingImageReader->GetOutput());
  resultImageWriter->SetInput(superElastixFilter->GetOutput<Image3DType>("ResultImageSink"));

  EXPECT_NO_THROW(superElastixFilter->SetBlueprint(blueprint));

  //Optional Update call
  //superElastixFilter->Update();

  // Update call on the writers triggers SuperElastix to configure and execute
  EXPECT_NO_THROW(resultImageWriter->Update());

377
}
378

379
TEST_F(RegistrationItkv4Test, FullyConfigured3d)
380
381
382
383
384
385
{
  /** make example blueprint configuration */
  blueprint = Blueprint::New();

  ParameterMapType component0Parameters;
  component0Parameters["NameOfClass"] = { "ItkImageRegistrationMethodv4Component" };
386
  component0Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
387
  blueprint->AddComponent("RegistrationMethod", component0Parameters);
388
389
390

  ParameterMapType component1Parameters;
  component1Parameters["NameOfClass"] = { "ItkImageSourceFixedComponent" };
391
  component1Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
392
  blueprint->AddComponent("FixedImageSource", component1Parameters);
393
394
395

  ParameterMapType component2Parameters;
  component2Parameters["NameOfClass"] = { "ItkImageSourceMovingComponent" };
396
  component2Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
397
  blueprint->AddComponent("MovingImageSource", component2Parameters);
398
399

  ParameterMapType component3Parameters;
400
  component3Parameters["NameOfClass"] = { "ItkImageSinkComponent" };
401
  component3Parameters["Dimensionality"] = { "3" }; // should be derived from the outputs
402
  blueprint->AddComponent("ResultImageSink", component3Parameters);
403
404
405

  ParameterMapType component4Parameters;
  component4Parameters["NameOfClass"] = { "DisplacementFieldItkImageFilterSinkComponent" };
406
  component4Parameters["Dimensionality"] = { "3" }; // should be derived from the outputs
407
  blueprint->AddComponent("ResultDisplacementFieldSink", component4Parameters);
408

409
410
  ParameterMapType component5Parameters;
  component5Parameters["NameOfClass"] = { "ItkANTSNeighborhoodCorrelationImageToImageMetricv4Component" };
411
  component5Parameters["Dimensionality"] = { "3" }; // should be derived from the inputs
412
  blueprint->AddComponent("Metric", component5Parameters);
413

414
415
416
417
  ParameterMapType component6Parameters;
  component6Parameters["NameOfClass"] = { "ItkTransformDisplacementFilterComponent" };
  component6Parameters["Dimensionality"] = { "3" }; // should be derived from the outputs
  blueprint->AddComponent("TransformDisplacementFilter", component6Parameters);
418

419
420
421
422
423
  ParameterMapType component7Parameters;
  component7Parameters["NameOfClass"] = { "ItkGradientDescentOptimizerv4Component" };
  component7Parameters["NumberOfIterations"] = { "1" };
  blueprint->AddComponent("Optimizer", component7Parameters);

424

425
426
427
428
429
  blueprint->AddComponent("ResampleFilter", { { "NameOfClass",    { "ItkResampleFilterComponent" } },
                                              { "Dimensionality", { "3" } } });
                                            
  blueprint->AddComponent("Transform",      { { "NameOfClass",    { "ItkGaussianExponentialDiffeomorphicTransformComponent" } },
                                              { "Dimensionality", { "3" } } });
430

431
  ParameterMapType connection1Parameters;
432
  connection1Parameters["NameOfInterface"] = { "itkImageFixedInterface" };
433
  blueprint->AddConnection("FixedImageSource", "RegistrationMethod", connection1Parameters);
434
435

  ParameterMapType connection2Parameters;
436
  connection2Parameters["NameOfInterface"] = { "itkImageMovingInterface" };
437
  blueprint->AddConnection("MovingImageSource", "RegistrationMethod", connection2Parameters);
438
439

  ParameterMapType connection3Parameters;
440
  connection3Parameters["NameOfInterface"] = { "itkImageInterface" };
441
  blueprint->AddConnection("ResampleFilter", "ResultImageSink", connection3Parameters);
442
443
444

  ParameterMapType connection4Parameters;
  connection4Parameters["NameOfInterface"] = { "DisplacementFieldItkImageSourceInterface" };
445
  blueprint->AddConnection("TransformDisplacementFilter", "ResultDisplacementFieldSink", connection4Parameters);
446

447
448
  ParameterMapType connection5Parameters;
  connection5Parameters["NameOfInterface"] = { "itkMetricv4Interface" };
449
  blueprint->AddConnection("Metric", "RegistrationMethod", connection5Parameters);
450
  
451
  blueprint->AddConnection("FixedImageSource", "Transform", { {} });
452
  blueprint->AddConnection("Transform", "RegistrationMethod", { {} }); 
453
  blueprint->AddConnection("Optimizer", "RegistrationMethod", { {} });
454
455
  blueprint->AddConnection("RegistrationMethod", "TransformDisplacementFilter", { {} });
  blueprint->AddConnection("FixedImageSource", "TransformDisplacementFilter", { {} });
456
457
458
  blueprint->AddConnection("RegistrationMethod", "ResampleFilter", { {} });
  blueprint->AddConnection("FixedImageSource", "ResampleFilter", { {} });
  blueprint->AddConnection("MovingImageSource", "ResampleFilter", { {} });
459

460
461
462
  // Instantiate SuperElastix
  SuperElastixFilterType::Pointer superElastixFilter;
  EXPECT_NO_THROW(superElastixFilter = SuperElastixFilterType::New());
463

464
  // Data manager provides the paths to the input and output data for unit tests
465
  DataManagerType::Pointer dataManager = DataManagerType::New();
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

  // Set up the readers and writers
  ImageReader3DType::Pointer fixedImageReader = ImageReader3DType::New();
  fixedImageReader->SetFileName(dataManager->GetInputFile("sphereA3d.mhd"));

  ImageReader3DType::Pointer movingImageReader = ImageReader3DType::New();
  movingImageReader->SetFileName(dataManager->GetInputFile("sphereB3d.mhd"));

  ImageWriter3DType::Pointer resultImageWriter = ImageWriter3DType::New();
  resultImageWriter->SetFileName(dataManager->GetOutputFile("RegistrationItkv4Test_DisplacementField_image.mhd"));

  DisplacementImageWriter3DType::Pointer resultDisplacementWriter = DisplacementImageWriter3DType::New();
  resultDisplacementWriter->SetFileName(dataManager->GetOutputFile("RegistrationItkv4Test_DisplacementField_displacement.mhd"));


  // Connect SuperElastix in an itk pipeline
  superElastixFilter->SetInput("FixedImageSource", fixedImageReader->GetOutput());
  superElastixFilter->SetInput("MovingImageSource", movingImageReader->GetOutput());
  resultImageWriter->SetInput(superElastixFilter->GetOutput<Image3DType>("ResultImageSink"));
  resultDisplacementWriter->SetInput(superElastixFilter->GetOutput<DisplacementImage3DType>("ResultDisplacementFieldSink"));

  EXPECT_NO_THROW(superElastixFilter->SetBlueprint(blueprint));

  //Optional Update call
  //superElastixFilter->Update();

  // Update call on the writers triggers SuperElastix to configure and execute
  EXPECT_NO_THROW(resultImageWriter->Update());
  EXPECT_NO_THROW(resultDisplacementWriter->Update());

496
497
  blueprint->WriteBlueprint(dataManager->GetOutputFile("RegistrationItkv4Test_DisplacementField_network.dot"));

498
}
499
} // namespace selx
500