Skip to content

Commit 608c7b0

Browse files
committed
Merge pull request #43 from naucoin/2979-support-for-cli-point-coordinateSystem-files
2979 support for cli point coordinate system files @naucoin Verified build against BRAINSTools, and no compilation issues were presented.
2 parents 18cdc5a + d7d3c9c commit 608c7b0

File tree

6 files changed

+217
-2
lines changed

6 files changed

+217
-2
lines changed

ModuleDescriptionParser/ModuleDescription.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ WriteParameterFile(const std::string& filename, bool withHandlesToBulkParameters
384384
&& (*pit).GetTag() != "transform"
385385
&& (*pit).GetTag() != "table"
386386
&& (*pit).GetTag() != "measurement"
387-
&& (*pit).GetTag() != "point" // point and region are special
387+
&& (*pit).GetTag() != "point" // point and point file and region are special
388+
&& (*pit).GetTag() != "pointfile"
388389
&& (*pit).GetTag() != "region")))
389390
{
390391
rtp << (*pit).GetName() << " = "

ModuleDescriptionParser/ModuleDescription.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<xsd:element name="string" type="paramType"/>
3232
<xsd:element name="string-vector" type="paramType"/>
3333
<xsd:element name="point" type="pointType"/>
34+
<xsd:element name="pointfile" type="pointType"/>
3435
<xsd:element name="point-vector" type="pointType"/>
3536
<xsd:element name="region" type="pointType"/>
3637
<xsd:element name="region-vector" type="pointType"/>

ModuleDescriptionParser/ModuleDescriptionParser.cxx

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ startElement(void *userData, const char *element, const char **attrs)
7878
ps->LastData[ps->Depth].clear();
7979

8080
// Check for a valid module description file
81-
//
81+
//
8282
if (ps->Depth == 0 && (name != "executable") )
8383
{
8484
std::string error("ModuleDescriptionParser Error: <executable> must be the outer most tag. <" + name + std::string("> was found instead."));
@@ -513,6 +513,97 @@ startElement(void *userData, const char *element, const char **attrs)
513513
}
514514
parameter->SetTag(name);
515515
}
516+
else if (name == "pointfile")
517+
{
518+
if (!group || (ps->OpenTags.top() != "parameters"))
519+
{
520+
std::string error("ModuleDescriptionParser Error: <" + name + "> can only be used inside <parameters> but was found inside <" + ps->OpenTags.top() + ">");
521+
if (ps->ErrorDescription.size() == 0)
522+
{
523+
ps->ErrorDescription = error;
524+
ps->ErrorLine = XML_GetCurrentLineNumber(ps->Parser);
525+
ps->Error = true;
526+
}
527+
ps->OpenTags.push(name);
528+
delete parameter;
529+
return;
530+
}
531+
parameter = new ModuleParameter;
532+
int attrCount = XML_GetSpecifiedAttributeCount(ps->Parser);
533+
534+
// Parse attribute pairs
535+
parameter->SetCPPType("std::string");
536+
parameter->SetType("scalar");
537+
for (int attr=0; attr < (attrCount / 2); attr++)
538+
{
539+
if ((strcmp(attrs[2*attr], "multiple") == 0))
540+
{
541+
if ((strcmp(attrs[2*attr+1], "true") == 0) ||
542+
(strcmp(attrs[2*attr+1], "false") == 0))
543+
{
544+
parameter->SetMultiple(attrs[2*attr+1]);
545+
if (strcmp(attrs[2*attr+1], "true") == 0)
546+
{
547+
parameter->SetCPPType("std::vector<std::string>");
548+
parameter->SetArgType("std::string");
549+
}
550+
}
551+
else
552+
{
553+
std::string error("ModuleDescriptionParser Error: \"" + std::string(attrs[2*attr+1]) + "\" is not a valid argument for the attribute \"multiple\". Only \"true\" and \"false\" are accepted.");
554+
if (ps->ErrorDescription.size() == 0)
555+
{
556+
ps->ErrorDescription = error;
557+
ps->ErrorLine = XML_GetCurrentLineNumber(ps->Parser);
558+
ps->Error = true;
559+
}
560+
ps->OpenTags.push(name);
561+
delete parameter;
562+
return;
563+
}
564+
}
565+
else if ((strcmp(attrs[2*attr], "fileExtensions") == 0))
566+
{
567+
parameter->SetFileExtensionsAsString(attrs[2*attr+1]);
568+
}
569+
else if ((strcmp(attrs[2*attr], "coordinateSystem") == 0))
570+
{
571+
if ((strcmp(attrs[2*attr+1], "ijk") == 0) ||
572+
(strcmp(attrs[2*attr+1], "lps") == 0) ||
573+
(strcmp(attrs[2*attr+1], "ras") == 0))
574+
{
575+
parameter->SetCoordinateSystem(attrs[2*attr+1]);
576+
}
577+
else
578+
{
579+
std::string error("ModuleDescriptionParser Error: \"" + std::string(attrs[2*attr+1]) + "\" is not a valid coordinate system. Only \"ijk\", \"lps\" and \"ras\" are accepted.");
580+
if (ps->ErrorDescription.size() == 0)
581+
{
582+
ps->ErrorDescription = error;
583+
ps->ErrorLine = XML_GetCurrentLineNumber(ps->Parser);
584+
ps->Error = true;
585+
}
586+
ps->OpenTags.push(name);
587+
delete parameter;
588+
return;
589+
}
590+
}
591+
else
592+
{
593+
std::string error("ModuleDescriptionParser Error: \"" + std::string(attrs[2*attr]) + "\" is not a valid attribute for \"" + name + "\". Only \"multiple\" and \"fileExtensions\" are accepted.");
594+
if (ps->ErrorDescription.size() == 0)
595+
{
596+
ps->ErrorDescription = error;
597+
ps->ErrorLine = XML_GetCurrentLineNumber(ps->Parser);
598+
ps->Error = true;
599+
}
600+
ps->OpenTags.push(name);
601+
delete parameter;
602+
return;
603+
}
604+
}
605+
parameter->SetTag(name);
606+
}
516607
else if (name == "region")
517608
{
518609
if (!group || (ps->OpenTags.top() != "parameters"))
@@ -1623,6 +1714,15 @@ endElement(void *userData, const char *element)
16231714
}
16241715
ps->CurrentParameter = 0;
16251716
}
1717+
else if (group && parameter && (name == "pointfile"))
1718+
{
1719+
ps->CurrentGroup->AddParameter(*parameter);
1720+
if (ps->CurrentParameter)
1721+
{
1722+
delete ps->CurrentParameter;
1723+
}
1724+
ps->CurrentParameter = 0;
1725+
}
16261726
else if (group && parameter && (name == "region"))
16271727
{
16281728
ps->CurrentGroup->AddParameter(*parameter);

ModuleDescriptionParser/Testing/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ add_test(
4040
NAME Parser1Test2
4141
COMMAND ${Slicer_LAUNCH_COMMAND} $<TARGET_FILE:Parser1Test> ${TEST_DATA}/ParserTest2.xml)
4242

43+
add_test(
44+
NAME Parser1Test3
45+
COMMAND ${Slicer_LAUNCH_COMMAND} $<TARGET_FILE:Parser1Test> ${TEST_DATA}/ParserTest3.xml)
46+
4347
add_test(
4448
NAME ModuleDescriptionTest
4549
COMMAND ${Slicer_LAUNCH_COMMAND} $<TARGET_FILE:${KIT}CxxTests> ModuleDescriptionTest ${TEST_DATA}

ModuleDescriptionParser/Testing/ModuleDescriptionTest.cxx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
//---------------------------------------------------------------------------
1010
bool TestReadParameterFileWithMissingValue();
11+
bool TestParameterFileWithPointFile();
1112

1213
//---------------------------------------------------------------------------
1314
namespace
@@ -31,6 +32,11 @@ int ModuleDescriptionTest(int argc, char * argv[])
3132
return EXIT_FAILURE;
3233
}
3334

35+
if (!TestParameterFileWithPointFile())
36+
{
37+
return EXIT_FAILURE;
38+
}
39+
3440
return EXIT_SUCCESS;
3541
}
3642

@@ -99,3 +105,68 @@ bool TestReadParameterFileWithMissingValue()
99105

100106
return true;
101107
}
108+
109+
//---------------------------------------------------------------------------
110+
bool TestParameterFileWithPointFile()
111+
{
112+
std::string input = INPUT_DIR
113+
+ "/parameter-file-with-pointfile-slicer-issue2979.params";
114+
115+
ModuleParameterGroup group;
116+
117+
{
118+
ModuleParameter parameter;
119+
parameter.SetName("Input Fiducial File");
120+
parameter.SetDefault("input.fcsv");
121+
parameter.SetTag("pointfile");
122+
parameter.SetMultiple("false");
123+
parameter.SetFileExtensionsAsString(".fcsv");
124+
parameter.SetCoordinateSystem("ras");
125+
parameter.SetChannel("input");
126+
group.AddParameter(parameter);
127+
}
128+
129+
{
130+
ModuleParameter parameter;
131+
parameter.SetName("Output Fiducial File");
132+
parameter.SetDefault("output.fcsv");
133+
parameter.SetTag("pointfile");
134+
parameter.SetMultiple("false");
135+
parameter.SetFileExtensionsAsString(".fcsv");
136+
parameter.SetCoordinateSystem("lps");
137+
parameter.SetChannel("output");
138+
group.AddParameter(parameter);
139+
}
140+
141+
ModuleDescription desc;
142+
desc.AddParameterGroup(group);
143+
144+
if (!desc.HasParameter("Input Fiducial File") || !desc.HasParameter("Output Fiducial File"))
145+
{
146+
std::cerr << "Line " << __LINE__
147+
<< " - Parameters are expected."
148+
<< std::endl;
149+
return false;
150+
}
151+
if (!desc.WriteParameterFile(input, true))
152+
{
153+
std::cerr << "Line " << __LINE__
154+
<< " - Unable to write parameter file "
155+
<< input
156+
<< std::endl;
157+
return false;
158+
}
159+
160+
ModuleDescription readDesc;
161+
if (readDesc.ReadParameterFile(input))
162+
{
163+
std::cerr << "Line " << __LINE__
164+
<< " - Unable to read parameter file, something changed"
165+
<< ", but it was reading into an empty description "
166+
<< input
167+
<< std::endl;
168+
return false;
169+
}
170+
171+
return true;
172+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<executable>
3+
<category>Developer Tools</category>
4+
<title>Fiducial XML Parsing Test</title>
5+
<description><![CDATA[Shows point and pointfiles.]]></description>
6+
<version>0.1.0.$Revision$(alpha)</version>
7+
<license/>
8+
<contributor>Nicole Aucoin (BWH)</contributor>
9+
<acknowledgements><![CDATA[This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149.]]></acknowledgements>
10+
<parameters>
11+
<label>Fiducial Input Parameters</label>
12+
<description><![CDATA[Parameters that describe input fidicuals.]]></description>
13+
<point multiple="true" coordinateSystem="ras">
14+
<name>seed</name>
15+
<label>Seeds</label>
16+
<longflag>--seed</longflag>
17+
<description><![CDATA[Lists of points in the CLI correspond to slicer fiducial lists]]></description>
18+
<default>0,0,0</default>
19+
</point>
20+
<pointfile multiple="true" fileExtensions=".fcsv" coordinateSystem="lps">
21+
<name>seedsFile</name>
22+
<description><![CDATA[Test file of input fiducials, compared to seeds]]></description>
23+
<label>Seeds file</label>
24+
<longflag>seedsFile</longflag>
25+
<channel>input</channel>
26+
</pointfile>
27+
</parameters>
28+
<parameters>
29+
<label>Fiducial file return types</label>
30+
<pointfile fileExtensions=".fcsv" coordinateSystem="lps">
31+
<name>seedsOutFile</name>
32+
<label>Output Fiducials File</label>
33+
<description><![CDATA[Output file to read back in.]]></description>
34+
<longflag>seedsOutFile</longflag>
35+
<channel>output</channel>
36+
</pointfile>
37+
</parameters>
38+
</executable>

0 commit comments

Comments
 (0)