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 "vtkStringArray.h"
16 #include "vtkTable.h"
17 #include "vtkMultiCorrelativeStatistics.h"
18
19 //=============================================================================
TestMultiCorrelativeStatistics(int,char * [])20 int TestMultiCorrelativeStatistics( int, char *[] )
21 {
22 int testStatus = 0;
23
24 /* */
25 double mingledData[] =
26 {
27 46, 45,
28 47, 49,
29 46, 47,
30 46, 46,
31 47, 46,
32 47, 49,
33 49, 49,
34 47, 45,
35 50, 50,
36 46, 46,
37 51, 50,
38 48, 48,
39 52, 54,
40 48, 47,
41 52, 52,
42 49, 49,
43 53, 54,
44 50, 50,
45 53, 54,
46 50, 52,
47 53, 53,
48 50, 51,
49 54, 54,
50 49, 49,
51 52, 52,
52 50, 51,
53 52, 52,
54 49, 47,
55 48, 48,
56 48, 50,
57 46, 48,
58 47, 47
59 };
60 int nVals = 32;
61
62 const char m0Name[] = "M0";
63 vtkDoubleArray* dataset1Arr = vtkDoubleArray::New();
64 dataset1Arr->SetNumberOfComponents( 1 );
65 dataset1Arr->SetName( m0Name );
66
67 const char m1Name[] = "M1";
68 vtkDoubleArray* dataset2Arr = vtkDoubleArray::New();
69 dataset2Arr->SetNumberOfComponents( 1 );
70 dataset2Arr->SetName( m1Name );
71
72 const char m2Name[] = "M2";
73 vtkDoubleArray* dataset3Arr = vtkDoubleArray::New();
74 dataset3Arr->SetNumberOfComponents( 1 );
75 dataset3Arr->SetName( m2Name );
76
77 for ( int i = 0; i < nVals; ++ i )
78 {
79 int ti = i << 1;
80 dataset1Arr->InsertNextValue( mingledData[ti] );
81 dataset2Arr->InsertNextValue( mingledData[ti + 1] );
82 dataset3Arr->InsertNextValue( i != 12 ? -1. : -1.001 );
83 }
84
85 vtkTable* datasetTable = vtkTable::New();
86 datasetTable->AddColumn( dataset1Arr );
87 dataset1Arr->Delete();
88 datasetTable->AddColumn( dataset2Arr );
89 dataset2Arr->Delete();
90 datasetTable->AddColumn( dataset3Arr );
91 dataset3Arr->Delete();
92
93 // Set multi-correlative statistics algorithm and its input data port
94 vtkMultiCorrelativeStatistics* mcs = vtkMultiCorrelativeStatistics::New();
95
96 // First verify that absence of input does not cause trouble
97 cout << "## Verifying that absence of input does not cause trouble... ";
98 mcs->Update();
99 cout << "done.\n";
100
101 // Prepare first test with data
102 mcs->SetInputData( vtkStatisticsAlgorithm::INPUT_DATA, datasetTable );
103
104 datasetTable->Delete();
105
106 // Select Column Pairs of Interest ( Learn Mode )
107 mcs->SetColumnStatus( m0Name, 1 );
108 mcs->SetColumnStatus( m1Name, 1 );
109 mcs->RequestSelectedColumns();
110 mcs->ResetAllColumnStates();
111 mcs->SetColumnStatus( m0Name, 1 );
112 mcs->SetColumnStatus( m1Name, 1 );
113 mcs->SetColumnStatus( m2Name, 1 );
114 mcs->SetColumnStatus( m2Name, 0 );
115 mcs->SetColumnStatus( m2Name, 1 );
116 mcs->RequestSelectedColumns();
117 mcs->RequestSelectedColumns(); // Try a duplicate entry. This should have no effect.
118 mcs->SetColumnStatus( m0Name, 0 );
119 mcs->SetColumnStatus( m2Name, 0 );
120 mcs->SetColumnStatus( "Metric 3", 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( mcs->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
130
131 cout << "## Calculated the following statistics for data set:\n";
132 for ( unsigned int b = 0; b < outputMetaDS->GetNumberOfBlocks(); ++ b )
133 {
134 vtkTable* outputMeta = vtkTable::SafeDownCast( outputMetaDS->GetBlock( b ) );
135
136 if ( b == 0 )
137 {
138 cout << "Primary Statistics\n";
139 }
140 else
141 {
142 cout << "Derived Statistics " << ( b - 1 ) << "\n";
143 }
144
145 outputMeta->Dump();
146 }
147
148 // Test Assess Mode
149 vtkMultiBlockDataSet* paramsTables = vtkMultiBlockDataSet::New();
150 paramsTables->ShallowCopy( outputMetaDS );
151
152 mcs->SetInputData( vtkStatisticsAlgorithm::INPUT_MODEL, paramsTables );
153 paramsTables->Delete();
154
155 // Test Assess only (Do not recalculate nor rederive a model)
156 mcs->SetLearnOption( false );
157 mcs->SetDeriveOption( false );
158 mcs->SetAssessOption( true );
159 mcs->Update();
160
161 vtkTable* outputData = mcs->GetOutput();
162 outputData->Dump();
163
164 // Threshold for outlier detection
165 double threshold = 4.;
166 int nOutliers = 0;
167 int tableIdx[] = { 0, 1, 3 };
168
169 cout << "## Searching for outliers such that "
170 << outputData->GetColumnName( tableIdx[2] )
171 << " > "
172 << threshold
173 << "\n";
174
175 cout << " Found the following outliers:\n";
176 for ( int i = 0; i < 3; ++ i )
177 {
178 cout << " "
179 << outputData->GetColumnName( tableIdx[i] );
180 }
181 cout << "\n";
182
183 for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
184 {
185 if ( outputData->GetValue( r, tableIdx[2] ).ToDouble() > threshold )
186 {
187 ++ nOutliers;
188
189 for ( int i = 0; i < 3; ++ i )
190 {
191 cout << " "
192 << outputData->GetValue( r, tableIdx[i] ).ToString()
193 << " ";
194 }
195 cout << "\n";
196 }
197 }
198
199 if ( nOutliers != 3 )
200 {
201 vtkGenericWarningMacro("Expected 3 outliers, found " << nOutliers << ".");
202 testStatus = 1;
203 }
204
205 mcs->Delete();
206
207 return testStatus;
208 }
209
210