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