dspx 0.1.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/.github/workflows/ci.yml +185 -0
  2. package/.vscode/c_cpp_properties.json +17 -0
  3. package/.vscode/settings.json +68 -0
  4. package/.vscode/tasks.json +28 -0
  5. package/DISCLAIMER.md +32 -0
  6. package/LICENSE +21 -0
  7. package/README.md +1803 -0
  8. package/ROADMAP.md +192 -0
  9. package/TECHNICAL_DEBT.md +165 -0
  10. package/binding.gyp +65 -0
  11. package/docs/ADVANCED_LOGGER_FEATURES.md +598 -0
  12. package/docs/AUTHENTICATION_SECURITY.md +396 -0
  13. package/docs/BACKEND_IMPROVEMENTS.md +399 -0
  14. package/docs/CHEBYSHEV_BIQUAD_EQ_IMPLEMENTATION.md +405 -0
  15. package/docs/FFT_IMPLEMENTATION.md +490 -0
  16. package/docs/FFT_IMPROVEMENTS_SUMMARY.md +387 -0
  17. package/docs/FFT_USER_GUIDE.md +494 -0
  18. package/docs/FILTERS_IMPLEMENTATION.md +260 -0
  19. package/docs/FILTER_API_GUIDE.md +418 -0
  20. package/docs/FIR_SIMD_OPTIMIZATION.md +175 -0
  21. package/docs/LOGGER_API_REFERENCE.md +350 -0
  22. package/docs/NOTCH_FILTER_QUICK_REF.md +121 -0
  23. package/docs/PHASE2_TESTS_AND_NOTCH_FILTER.md +341 -0
  24. package/docs/PHASES_5_7_SUMMARY.md +403 -0
  25. package/docs/PIPELINE_FILTER_INTEGRATION.md +446 -0
  26. package/docs/SIMD_OPTIMIZATIONS.md +211 -0
  27. package/docs/TEST_MIGRATION_SUMMARY.md +173 -0
  28. package/docs/TIMESERIES_IMPLEMENTATION_SUMMARY.md +322 -0
  29. package/docs/TIMESERIES_QUICK_REF.md +85 -0
  30. package/docs/advanced.md +559 -0
  31. package/docs/time-series-guide.md +617 -0
  32. package/docs/time-series-migration.md +376 -0
  33. package/jest.config.js +37 -0
  34. package/package.json +42 -0
  35. package/prebuilds/linux-x64/dsp-ts-redis.node +0 -0
  36. package/prebuilds/win32-x64/dsp-ts-redis.node +0 -0
  37. package/scripts/test.js +24 -0
  38. package/src/build/dsp-ts-redis.node +0 -0
  39. package/src/native/DspPipeline.cc +675 -0
  40. package/src/native/DspPipeline.h +44 -0
  41. package/src/native/FftBindings.cc +817 -0
  42. package/src/native/FilterBindings.cc +1001 -0
  43. package/src/native/IDspStage.h +53 -0
  44. package/src/native/adapters/InterpolatorStage.h +201 -0
  45. package/src/native/adapters/MeanAbsoluteValueStage.h +289 -0
  46. package/src/native/adapters/MovingAverageStage.h +306 -0
  47. package/src/native/adapters/RectifyStage.h +88 -0
  48. package/src/native/adapters/ResamplerStage.h +238 -0
  49. package/src/native/adapters/RmsStage.h +299 -0
  50. package/src/native/adapters/SscStage.h +121 -0
  51. package/src/native/adapters/VarianceStage.h +307 -0
  52. package/src/native/adapters/WampStage.h +114 -0
  53. package/src/native/adapters/WaveformLengthStage.h +115 -0
  54. package/src/native/adapters/ZScoreNormalizeStage.h +326 -0
  55. package/src/native/core/FftEngine.cc +441 -0
  56. package/src/native/core/FftEngine.h +224 -0
  57. package/src/native/core/FirFilter.cc +324 -0
  58. package/src/native/core/FirFilter.h +149 -0
  59. package/src/native/core/IirFilter.cc +576 -0
  60. package/src/native/core/IirFilter.h +210 -0
  61. package/src/native/core/MovingAbsoluteValueFilter.cc +17 -0
  62. package/src/native/core/MovingAbsoluteValueFilter.h +135 -0
  63. package/src/native/core/MovingAverageFilter.cc +18 -0
  64. package/src/native/core/MovingAverageFilter.h +135 -0
  65. package/src/native/core/MovingFftFilter.cc +291 -0
  66. package/src/native/core/MovingFftFilter.h +203 -0
  67. package/src/native/core/MovingVarianceFilter.cc +194 -0
  68. package/src/native/core/MovingVarianceFilter.h +114 -0
  69. package/src/native/core/MovingZScoreFilter.cc +215 -0
  70. package/src/native/core/MovingZScoreFilter.h +113 -0
  71. package/src/native/core/Policies.h +352 -0
  72. package/src/native/core/RmsFilter.cc +18 -0
  73. package/src/native/core/RmsFilter.h +131 -0
  74. package/src/native/core/SscFilter.cc +16 -0
  75. package/src/native/core/SscFilter.h +137 -0
  76. package/src/native/core/WampFilter.cc +16 -0
  77. package/src/native/core/WampFilter.h +101 -0
  78. package/src/native/core/WaveformLengthFilter.cc +17 -0
  79. package/src/native/core/WaveformLengthFilter.h +98 -0
  80. package/src/native/utils/CircularBufferArray.cc +336 -0
  81. package/src/native/utils/CircularBufferArray.h +62 -0
  82. package/src/native/utils/CircularBufferVector.cc +145 -0
  83. package/src/native/utils/CircularBufferVector.h +45 -0
  84. package/src/native/utils/NapiUtils.cc +53 -0
  85. package/src/native/utils/NapiUtils.h +21 -0
  86. package/src/native/utils/SimdOps.h +870 -0
  87. package/src/native/utils/SlidingWindowFilter.cc +239 -0
  88. package/src/native/utils/SlidingWindowFilter.h +159 -0
  89. package/src/native/utils/TimeSeriesBuffer.cc +205 -0
  90. package/src/native/utils/TimeSeriesBuffer.h +140 -0
  91. package/src/ts/CircularLogBuffer.ts +87 -0
  92. package/src/ts/DriftDetector.ts +331 -0
  93. package/src/ts/TopicRouter.ts +428 -0
  94. package/src/ts/__tests__/AdvancedDsp.test.ts +585 -0
  95. package/src/ts/__tests__/AuthAndEdgeCases.test.ts +241 -0
  96. package/src/ts/__tests__/Chaining.test.ts +387 -0
  97. package/src/ts/__tests__/ChebyshevBiquad.test.ts +229 -0
  98. package/src/ts/__tests__/CircularLogBuffer.test.ts +158 -0
  99. package/src/ts/__tests__/DriftDetector.test.ts +389 -0
  100. package/src/ts/__tests__/Fft.test.ts +484 -0
  101. package/src/ts/__tests__/ListState.test.ts +153 -0
  102. package/src/ts/__tests__/Logger.test.ts +208 -0
  103. package/src/ts/__tests__/LoggerAdvanced.test.ts +319 -0
  104. package/src/ts/__tests__/LoggerMinor.test.ts +247 -0
  105. package/src/ts/__tests__/MeanAbsoluteValue.test.ts +398 -0
  106. package/src/ts/__tests__/MovingAverage.test.ts +322 -0
  107. package/src/ts/__tests__/RMS.test.ts +315 -0
  108. package/src/ts/__tests__/Rectify.test.ts +272 -0
  109. package/src/ts/__tests__/Redis.test.ts +456 -0
  110. package/src/ts/__tests__/SlopeSignChange.test.ts +166 -0
  111. package/src/ts/__tests__/Tap.test.ts +164 -0
  112. package/src/ts/__tests__/TimeBasedExpiration.test.ts +124 -0
  113. package/src/ts/__tests__/TimeBasedRmsAndMav.test.ts +231 -0
  114. package/src/ts/__tests__/TimeBasedVarianceAndZScore.test.ts +284 -0
  115. package/src/ts/__tests__/TimeSeries.test.ts +254 -0
  116. package/src/ts/__tests__/TopicRouter.test.ts +332 -0
  117. package/src/ts/__tests__/TopicRouterAdvanced.test.ts +483 -0
  118. package/src/ts/__tests__/TopicRouterPriority.test.ts +487 -0
  119. package/src/ts/__tests__/Variance.test.ts +509 -0
  120. package/src/ts/__tests__/WaveformLength.test.ts +147 -0
  121. package/src/ts/__tests__/WillisonAmplitude.test.ts +197 -0
  122. package/src/ts/__tests__/ZScoreNormalize.test.ts +459 -0
  123. package/src/ts/advanced-dsp.ts +566 -0
  124. package/src/ts/backends.ts +1137 -0
  125. package/src/ts/bindings.ts +1225 -0
  126. package/src/ts/easter-egg.ts +42 -0
  127. package/src/ts/examples/MeanAbsoluteValue/test-state.ts +99 -0
  128. package/src/ts/examples/MeanAbsoluteValue/test-streaming.ts +269 -0
  129. package/src/ts/examples/MovingAverage/test-state.ts +85 -0
  130. package/src/ts/examples/MovingAverage/test-streaming.ts +188 -0
  131. package/src/ts/examples/RMS/test-state.ts +97 -0
  132. package/src/ts/examples/RMS/test-streaming.ts +253 -0
  133. package/src/ts/examples/Rectify/test-state.ts +107 -0
  134. package/src/ts/examples/Rectify/test-streaming.ts +242 -0
  135. package/src/ts/examples/Variance/test-state.ts +195 -0
  136. package/src/ts/examples/Variance/test-streaming.ts +260 -0
  137. package/src/ts/examples/ZScoreNormalize/test-state.ts +277 -0
  138. package/src/ts/examples/ZScoreNormalize/test-streaming.ts +306 -0
  139. package/src/ts/examples/advanced-dsp-examples.ts +397 -0
  140. package/src/ts/examples/callbacks/advanced-router-features.ts +326 -0
  141. package/src/ts/examples/callbacks/benchmark-circular-buffer.ts +109 -0
  142. package/src/ts/examples/callbacks/monitoring-example.ts +265 -0
  143. package/src/ts/examples/callbacks/pipeline-callbacks-example.ts +137 -0
  144. package/src/ts/examples/callbacks/pooled-callbacks-example.ts +274 -0
  145. package/src/ts/examples/callbacks/priority-routing-example.ts +277 -0
  146. package/src/ts/examples/callbacks/production-topic-router.ts +214 -0
  147. package/src/ts/examples/callbacks/topic-based-logging.ts +161 -0
  148. package/src/ts/examples/chaining/test-chaining-redis.ts +113 -0
  149. package/src/ts/examples/chaining/test-chaining.ts +52 -0
  150. package/src/ts/examples/emg-features-example.ts +284 -0
  151. package/src/ts/examples/fft-example.ts +309 -0
  152. package/src/ts/examples/fft-examples.ts +349 -0
  153. package/src/ts/examples/filter-examples.ts +320 -0
  154. package/src/ts/examples/list-state-example.ts +131 -0
  155. package/src/ts/examples/logger-example.ts +91 -0
  156. package/src/ts/examples/notch-filter-examples.ts +243 -0
  157. package/src/ts/examples/phase5/drift-detection-example.ts +290 -0
  158. package/src/ts/examples/phase6-7/production-observability.ts +476 -0
  159. package/src/ts/examples/phase6-7/redis-timeseries-integration.ts +446 -0
  160. package/src/ts/examples/redis/redis-example.ts +202 -0
  161. package/src/ts/examples/redis-example.ts +202 -0
  162. package/src/ts/examples/simd-benchmark.ts +126 -0
  163. package/src/ts/examples/tap-debugging.ts +230 -0
  164. package/src/ts/examples/timeseries/comparison-example.ts +290 -0
  165. package/src/ts/examples/timeseries/iot-sensor-example.ts +143 -0
  166. package/src/ts/examples/timeseries/redis-streaming-example.ts +233 -0
  167. package/src/ts/examples/waveform-length-example.ts +139 -0
  168. package/src/ts/fft.ts +722 -0
  169. package/src/ts/filters.ts +1078 -0
  170. package/src/ts/index.ts +120 -0
  171. package/src/ts/types.ts +589 -0
  172. package/tsconfig.json +15 -0
@@ -0,0 +1,341 @@
1
+ # Advanced DSP Tests and Notch Filter Support
2
+
3
+ ## Summary
4
+
5
+ This document addresses two issues:
6
+
7
+ 1. Missing tests for newly implemented advanced DSP functions (Phase 2)
8
+ 2. Notch filter support in the DSP pipeline
9
+
10
+ ## Issue 1: Advanced DSP Function Tests ✅ COMPLETED
11
+
12
+ ### What Was Missing
13
+
14
+ Tests for the advanced DSP functions implemented in Phase 2:
15
+
16
+ - **Hjorth Parameters**: Activity, Mobility, Complexity
17
+ - **Spectral Features**: Centroid, Rolloff, Flux
18
+ - **Entropy Measures**: Shannon Entropy, Sample Entropy, Approximate Entropy
19
+ - **Stateful Trackers**: HjorthTracker, SpectralFeaturesTracker, EntropyTracker
20
+
21
+ ### Solution
22
+
23
+ Created comprehensive test file: `src/ts/__tests__/AdvancedDsp.test.ts`
24
+
25
+ ### Test Coverage (441 tests total, all passing)
26
+
27
+ #### Hjorth Parameters Tests
28
+
29
+ - ✅ Calculate Hjorth parameters for simple sine wave
30
+ - ✅ Calculate higher complexity for noisy signal
31
+ - ✅ Handle constant signal (zero variance edge case)
32
+ - ✅ Throw error for too short signal
33
+ - ✅ HjorthTracker with sliding window
34
+ - ✅ HjorthTracker returns null until window is full
35
+ - ✅ HjorthTracker reset functionality
36
+
37
+ #### Spectral Features Tests
38
+
39
+ - ✅ Calculate spectral centroid correctly
40
+ - ✅ Higher centroid for high-frequency signal
41
+ - ✅ Calculate spectral rolloff
42
+ - ✅ Calculate zero flux for identical spectra
43
+ - ✅ Calculate positive flux for different spectra
44
+ - ✅ Return 0 when no previous spectrum provided
45
+ - ✅ Calculate all spectral features (unified interface)
46
+ - ✅ Calculate flux when previous spectrum provided
47
+ - ✅ SpectralFeaturesTracker frame-by-frame tracking
48
+ - ✅ SpectralFeaturesTracker reset functionality
49
+
50
+ #### Entropy Tests
51
+
52
+ - ✅ Calculate zero entropy for constant signal
53
+ - ✅ Calculate higher entropy for random signal
54
+ - ✅ Handle different bin counts
55
+ - ✅ Sample Entropy (SampEn) for regular signal
56
+ - ✅ Higher SampEn for irregular signal
57
+ - ✅ Automatic tolerance when not provided
58
+ - ✅ Approximate Entropy (ApEn) for regular signal
59
+ - ✅ Higher ApEn for random signal
60
+ - ✅ Handle custom tolerance
61
+ - ✅ EntropyTracker with sliding window
62
+ - ✅ EntropyTracker returns null until window is full
63
+ - ✅ EntropyTracker reset functionality
64
+
65
+ #### Edge Cases
66
+
67
+ - ✅ Handle NaN values gracefully
68
+ - ✅ Handle empty spectrum
69
+ - ✅ Handle mismatched spectrum lengths
70
+ - ✅ Handle very small signals
71
+
72
+ ### Test Results
73
+
74
+ ```
75
+ # tests 441
76
+ # suites 107
77
+ # pass 441
78
+ # fail 0
79
+ ```
80
+
81
+ All tests passing! ✅
82
+
83
+ ---
84
+
85
+ ## Issue 2: Notch Filter Support in DSP Pipeline
86
+
87
+ ### The Problem
88
+
89
+ User tried to use:
90
+
91
+ ```typescript
92
+ const dsp = createDspPipeline().filter({ type: "notch" });
93
+ ```
94
+
95
+ This doesn't work for two reasons:
96
+
97
+ 1. **"notch" is a MODE, not a TYPE**
98
+ 2. **Filter stages in the pipeline are not yet implemented**
99
+
100
+ ### Understanding the API
101
+
102
+ #### Filter Types vs. Filter Modes
103
+
104
+ **Filter Types** (implementation/topology):
105
+
106
+ - `"fir"` - Finite Impulse Response
107
+ - `"iir"` - Infinite Impulse Response
108
+ - `"butterworth"` - Butterworth IIR
109
+ - `"chebyshev"` - Chebyshev IIR
110
+ - `"biquad"` - Biquad (2nd-order IIR sections)
111
+
112
+ **Filter Modes** (frequency response):
113
+
114
+ - `"lowpass"` - Pass low frequencies
115
+ - `"highpass"` - Pass high frequencies
116
+ - `"bandpass"` - Pass frequencies in a band
117
+ - `"bandstop"` or `"notch"` - Reject frequencies in a band (same thing!)
118
+
119
+ ### Correct Usage for Notch Filters
120
+
121
+ #### Option 1: FIR Notch Filter (Recommended)
122
+
123
+ ```typescript
124
+ import { FirFilter } from "./filters.js";
125
+
126
+ const notchFilter = FirFilter.createBandStop({
127
+ lowCutoffFrequency: 58, // Lower edge of notch
128
+ highCutoffFrequency: 62, // Upper edge of notch
129
+ sampleRate: 1000,
130
+ order: 101,
131
+ windowType: "hamming",
132
+ });
133
+
134
+ // Process signal
135
+ const filtered = await notchFilter.process(signal);
136
+ ```
137
+
138
+ #### Option 2: IIR Notch Filter (Butterworth)
139
+
140
+ ```typescript
141
+ import { IirFilter } from "./filters.js";
142
+
143
+ // Note: Butterworth doesn't have band-stop yet
144
+ // You would need to use cascaded high-pass and low-pass
145
+ // or wait for dedicated notch filter implementation
146
+ ```
147
+
148
+ #### Option 3: Using the Generic API (When Pipeline Supports Filters)
149
+
150
+ ```typescript
151
+ // This will work in the future when pipeline filter support is added:
152
+ const dsp = createDspPipeline().filter({
153
+ type: "fir", // ← TYPE: FIR or IIR
154
+ mode: "bandstop", // ← MODE: bandstop or notch (same thing)
155
+ lowCutoffFrequency: 58,
156
+ highCutoffFrequency: 62,
157
+ sampleRate: 1000,
158
+ order: 51,
159
+ });
160
+ ```
161
+
162
+ ### Current Limitation
163
+
164
+ The `filter()` method in `DspProcessor` currently throws an error:
165
+
166
+ ```
167
+ Filter stages in pipeline not yet implemented in C++ layer.
168
+ Use standalone filters with manual chaining instead.
169
+ ```
170
+
171
+ **Why?** Filter stages need to be integrated into the native C++ pipeline. Currently only these stages work:
172
+
173
+ - ✅ MovingAverage
174
+ - ✅ Rectify
175
+ - ✅ RMS
176
+ - ✅ Variance
177
+ - ✅ ZScoreNormalize
178
+ - ✅ MeanAbsoluteValue
179
+ - ✅ WaveformLength
180
+ - ✅ SlopeSignChange
181
+ - ✅ WillisonAmplitude
182
+
183
+ ### Workaround: Manual Chaining
184
+
185
+ Until pipeline filter support is added, use standalone filters:
186
+
187
+ ```typescript
188
+ import { createDspPipeline } from "./bindings.js";
189
+ import { FirFilter } from "./filters.js";
190
+
191
+ // Create pipeline for other operations
192
+ const dsp = createDspPipeline()
193
+ .MovingAverage({ mode: "moving", windowSize: 10 })
194
+ .Rectify({ mode: "full" });
195
+
196
+ // Create standalone notch filter
197
+ const notchFilter = FirFilter.createBandStop({
198
+ lowCutoffFrequency: 58,
199
+ highCutoffFrequency: 62,
200
+ sampleRate: 1000,
201
+ order: 51,
202
+ });
203
+
204
+ // Manual chaining
205
+ const samples = new Float32Array([...data]);
206
+ const pipelineOutput = await dsp.process(samples);
207
+ const finalOutput = await notchFilter.process(pipelineOutput);
208
+ ```
209
+
210
+ ### Examples Created
211
+
212
+ Created comprehensive examples file: `src/ts/examples/notch-filter-examples.ts`
213
+
214
+ **Covered Topics:**
215
+
216
+ 1. FIR Notch Filter for 60 Hz power line noise
217
+ 2. Cascaded notch filters (remove multiple harmonics)
218
+ 3. Real-time notch filtering (stateful processing)
219
+ 4. Notch filter design trade-offs
220
+ 5. Verifying notch filter performance
221
+ 6. Important API notes and usage guidelines
222
+
223
+ **Run examples:**
224
+
225
+ ```bash
226
+ npm run build
227
+ node src/ts/examples/notch-filter-examples.js
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Key Takeaways
233
+
234
+ ### For Advanced DSP Tests ✅
235
+
236
+ - **Status**: Fully implemented and tested
237
+ - **Coverage**: 30+ new tests covering all advanced DSP functions
238
+ - **All tests passing**: 441/441 tests pass
239
+
240
+ ### For Notch Filters ⚠️
241
+
242
+ - **API Clarification**: `"notch"` is a **mode**, not a **type**
243
+ - **Correct Method**: Use `FirFilter.createBandStop()` or `IirFilter.createBandStop()`
244
+ - **Pipeline Status**: Filter stages not yet implemented in C++ layer
245
+ - **Workaround**: Use standalone filters with manual chaining
246
+ - **Documentation**: Comprehensive examples provided
247
+
248
+ ### Files Created/Modified
249
+
250
+ **New Files:**
251
+
252
+ 1. `src/ts/__tests__/AdvancedDsp.test.ts` - Comprehensive test suite (583 lines)
253
+ 2. `src/ts/examples/notch-filter-examples.ts` - Complete notch filter guide (237 lines)
254
+
255
+ **Modified Files:**
256
+
257
+ - None (tests were added, no existing code changed)
258
+
259
+ ---
260
+
261
+ ## Future Work
262
+
263
+ ### Short Term
264
+
265
+ - [ ] Implement filter stage support in C++ DspPipeline
266
+ - [ ] Add band-stop mode to Butterworth and Chebyshev IIR filters
267
+ - [ ] Add dedicated IIR notch filter design (more efficient than band-stop)
268
+
269
+ ### Medium Term
270
+
271
+ - [ ] Add real-time frequency tracking for adaptive notch filters
272
+ - [ ] Implement cascaded notch filter optimization
273
+ - [ ] Add notch filter visualization tools
274
+
275
+ ---
276
+
277
+ ## Testing Instructions
278
+
279
+ ### Run Advanced DSP Tests Only
280
+
281
+ ```bash
282
+ npm test -- AdvancedDsp
283
+ ```
284
+
285
+ ### Run All Tests
286
+
287
+ ```bash
288
+ npm test
289
+ ```
290
+
291
+ ### Run Notch Filter Examples
292
+
293
+ ```bash
294
+ npm run build
295
+ node src/ts/examples/notch-filter-examples.js
296
+ ```
297
+
298
+ ---
299
+
300
+ ## API Quick Reference
301
+
302
+ ### Create Notch Filter (CORRECT ✅)
303
+
304
+ ```typescript
305
+ import { FirFilter } from "./filters.js";
306
+
307
+ const notch = FirFilter.createBandStop({
308
+ lowCutoffFrequency: 58,
309
+ highCutoffFrequency: 62,
310
+ sampleRate: 1000,
311
+ order: 51,
312
+ });
313
+ ```
314
+
315
+ ### Common Mistake (WRONG ❌)
316
+
317
+ ```typescript
318
+ // This doesn't work - "notch" is not a type!
319
+ const dsp = createDspPipeline().filter({type: "notch", ...})
320
+ ```
321
+
322
+ ### Correct Pipeline Usage (When Implemented)
323
+
324
+ ```typescript
325
+ const dsp = createDspPipeline().filter({
326
+ type: "fir", // TYPE
327
+ mode: "bandstop", // MODE (or "notch")
328
+ lowCutoffFrequency: 58,
329
+ highCutoffFrequency: 62,
330
+ sampleRate: 1000,
331
+ order: 51,
332
+ });
333
+ ```
334
+
335
+ ---
336
+
337
+ **Status**: ✅ All requested work completed
338
+
339
+ - Advanced DSP tests: ✅ 30+ tests, all passing
340
+ - Notch filter documentation: ✅ Comprehensive examples and API guide
341
+ - Code quality: ✅ 0 compilation errors, 0 test failures