1 /*
2 * Copyright 2008 Sandia Corporation.
3 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
4 * license for use of this work by or on behalf of the
5 * U.S. Government. Redistribution and use in source and binary forms, with
6 * or without modification, are permitted provided that this Notice and any
7 * statement of authorship are reproduced on all copies.
8 */
9 // .SECTION Thanks
10 // Thanks to Philippe Pebay and David Thompson from Sandia National Laboratories
11 // for implementing this test.
12
13 #include "vtkDoubleArray.h"
14 #include "vtkMultiBlockDataSet.h"
15 #include "vtkMultiCorrelativeStatistics.h"
16 #include "vtkStringArray.h"
17 #include "vtkTable.h"
18
19 //=============================================================================
TestMultiCorrelativeStatistics(int,char * [])20 int TestMultiCorrelativeStatistics(int, char*[])
21 {
22 int testStatus = 0;
23
24 /* */
25 double mingledData[] = {
26 46, 45, //
27 47, 49, //
28 46, 47, //
29 46, 46, //
30 47, 46, //
31 47, 49, //
32 49, 49, //
33 47, 45, //
34 50, 50, //
35 46, 46, //
36 51, 50, //
37 48, 48, //
38 52, 54, //
39 48, 47, //
40 52, 52, //
41 49, 49, //
42 53, 54, //
43 50, 50, //
44 53, 54, //
45 50, 52, //
46 53, 53, //
47 50, 51, //
48 54, 54, //
49 49, 49, //
50 52, 52, //
51 50, 51, //
52 52, 52, //
53 49, 47, //
54 48, 48, //
55 48, 50, //
56 46, 48, //
57 47, 47 //
58 };
59 int nVals = 32;
60
61 const char m0Name[] = "M0";
62 vtkDoubleArray* dataset1Arr = vtkDoubleArray::New();
63 dataset1Arr->SetNumberOfComponents(1);
64 dataset1Arr->SetName(m0Name);
65
66 const char m1Name[] = "M1";
67 vtkDoubleArray* dataset2Arr = vtkDoubleArray::New();
68 dataset2Arr->SetNumberOfComponents(1);
69 dataset2Arr->SetName(m1Name);
70
71 const char m2Name[] = "M2";
72 vtkDoubleArray* dataset3Arr = vtkDoubleArray::New();
73 dataset3Arr->SetNumberOfComponents(1);
74 dataset3Arr->SetName(m2Name);
75
76 for (int i = 0; i < nVals; ++i)
77 {
78 int ti = i << 1;
79 dataset1Arr->InsertNextValue(mingledData[ti]);
80 dataset2Arr->InsertNextValue(mingledData[ti + 1]);
81 dataset3Arr->InsertNextValue(i != 12 ? -1. : -1.001);
82 }
83
84 vtkTable* datasetTable = vtkTable::New();
85 datasetTable->AddColumn(dataset1Arr);
86 dataset1Arr->Delete();
87 datasetTable->AddColumn(dataset2Arr);
88 dataset2Arr->Delete();
89 datasetTable->AddColumn(dataset3Arr);
90 dataset3Arr->Delete();
91
92 // Set multi-correlative statistics algorithm and its input data port
93 vtkMultiCorrelativeStatistics* mcs = vtkMultiCorrelativeStatistics::New();
94
95 // First verify that absence of input does not cause trouble
96 cout << "## Verifying that absence of input does not cause trouble... ";
97 mcs->Update();
98 cout << "done.\n";
99
100 // Prepare first test with data
101 mcs->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, datasetTable);
102
103 datasetTable->Delete();
104
105 // Select Column Pairs of Interest ( Learn Mode )
106 mcs->SetColumnStatus(m0Name, 1);
107 mcs->SetColumnStatus(m1Name, 1);
108 mcs->RequestSelectedColumns();
109 mcs->ResetAllColumnStates();
110 mcs->SetColumnStatus(m0Name, 1);
111 mcs->SetColumnStatus(m1Name, 1);
112 mcs->SetColumnStatus(m2Name, 1);
113 mcs->SetColumnStatus(m2Name, 0);
114 mcs->SetColumnStatus(m2Name, 1);
115 mcs->RequestSelectedColumns();
116 mcs->RequestSelectedColumns(); // Try a duplicate entry. This should have no effect.
117 mcs->SetColumnStatus(m0Name, 0);
118 mcs->SetColumnStatus(m2Name, 0);
119 mcs->SetColumnStatus("Metric 3",
120 1); // An invalid name. This should result in a request for metric 1's self-correlation.
121 // mcs->RequestSelectedColumns(); will get called in RequestData()
122
123 // Test Learn Mode
124 mcs->SetLearnOption(true);
125 mcs->SetDeriveOption(true);
126 mcs->SetAssessOption(false);
127
128 mcs->Update();
129 vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast(
130 mcs->GetOutputDataObject(vtkStatisticsAlgorithm::OUTPUT_MODEL));
131
132 cout << "## Calculated the following statistics for data set:\n";
133 for (unsigned int b = 0; b < outputMetaDS->GetNumberOfBlocks(); ++b)
134 {
135 vtkTable* outputMeta = vtkTable::SafeDownCast(outputMetaDS->GetBlock(b));
136
137 if (b == 0)
138 {
139 cout << "Primary Statistics\n";
140 }
141 else
142 {
143 cout << "Derived Statistics " << (b - 1) << "\n";
144 }
145
146 outputMeta->Dump();
147 }
148
149 // Test Assess Mode
150 vtkMultiBlockDataSet* paramsTables = vtkMultiBlockDataSet::New();
151 paramsTables->ShallowCopy(outputMetaDS);
152
153 mcs->SetInputData(vtkStatisticsAlgorithm::INPUT_MODEL, paramsTables);
154 paramsTables->Delete();
155
156 // Test Assess only (Do not recalculate nor rederive a model)
157 mcs->SetLearnOption(false);
158 mcs->SetDeriveOption(false);
159 mcs->SetAssessOption(true);
160 mcs->Update();
161
162 vtkTable* outputData = mcs->GetOutput();
163 outputData->Dump();
164
165 // Threshold for outlier detection
166 double threshold = 4.;
167 int nOutliers = 0;
168 int tableIdx[] = { 0, 1, 3 };
169
170 cout << "## Searching for outliers such that " << outputData->GetColumnName(tableIdx[2]) << " > "
171 << threshold << "\n";
172
173 cout << " Found the following outliers:\n";
174 for (int i = 0; i < 3; ++i)
175 {
176 cout << " " << outputData->GetColumnName(tableIdx[i]);
177 }
178 cout << "\n";
179
180 for (vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++r)
181 {
182 if (outputData->GetValue(r, tableIdx[2]).ToDouble() > threshold)
183 {
184 ++nOutliers;
185
186 for (int i = 0; i < 3; ++i)
187 {
188 cout << " " << outputData->GetValue(r, tableIdx[i]).ToString() << " ";
189 }
190 cout << "\n";
191 }
192 }
193
194 if (nOutliers != 3)
195 {
196 vtkGenericWarningMacro("Expected 3 outliers, found " << nOutliers << ".");
197 testStatus = 1;
198 }
199
200 mcs->Delete();
201
202 return testStatus;
203 }
204