[175] | 1 | #include <string.h>
|
---|
| 2 | #include <stdlib.h>
|
---|
| 3 | #include <memory.h>
|
---|
| 4 | #include <stdio.h>
|
---|
| 5 | #include <math.h>
|
---|
| 6 | #include <tcl.h>
|
---|
| 7 |
|
---|
| 8 | /* ----------------------------------------------------------------- */
|
---|
| 9 | /* Peak detection using undecimated wavelet transform (UWT) */
|
---|
| 10 | /* ----------------------------------------------------------------- */
|
---|
| 11 |
|
---|
| 12 | /* Memory requirements */
|
---|
| 13 | /* tapped delay line: 24 registers */
|
---|
| 14 | /* noise buffer: 16 registers */
|
---|
| 15 |
|
---|
| 16 | #define UWT_ZERO 1000
|
---|
| 17 | #define UWT_LEVEL 3
|
---|
| 18 |
|
---|
| 19 | #define UWT_NOISE_BUFFER_SIZE 16
|
---|
| 20 | #define UWT_NOISE_BUFFER_SIZE_LOG2 4
|
---|
| 21 |
|
---|
| 22 | #define UWT_TYPICAL_START_TIME 16
|
---|
| 23 | #define UWT_TYPICAL_NOISE_TIME 16
|
---|
| 24 | #define UWT_MAX_RISE_TIME 40
|
---|
| 25 | #define UWT_MIN_PEAK_DIST 60
|
---|
| 26 |
|
---|
| 27 | #define UWT_SIGNAL_THRESHOLD 10
|
---|
| 28 |
|
---|
| 29 | static void uwt_bior31_step(int input, int *tap,
|
---|
| 30 | int *d_reg, int *a_reg, int *peak_reg, int *tmp1_reg, int *tmp2_reg, int *flag1_reg, int *flag2_reg, int *less_reg, int *more_reg,
|
---|
| 31 | int *d, int *a, int *peak, int *is_min, int *is_max, int level)
|
---|
| 32 | {
|
---|
| 33 | int i;
|
---|
| 34 | int index1 = 1 << (level - 1);
|
---|
| 35 | int index2 = 2 << (level - 1);
|
---|
| 36 | int index3 = 3 << (level - 1);
|
---|
| 37 | int peak_index = ((3 << (level - 1)) + 1) >> 1;
|
---|
| 38 | int peak_shift = ((level - 1) << 1) + (level - 1);
|
---|
| 39 |
|
---|
| 40 | int d_next, a_next, peak_next;
|
---|
| 41 | int tmp1_next, tmp2_next, less_next, more_next;
|
---|
| 42 |
|
---|
| 43 |
|
---|
| 44 | // Tapped delay line: shift one
|
---|
| 45 | for(i = index3; i > 0; --i)
|
---|
| 46 | {
|
---|
| 47 | tap[i] = tap[i-1];
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | // Input in register 0
|
---|
| 51 | tap[0] = input;
|
---|
| 52 |
|
---|
| 53 | *d = *d_reg;
|
---|
| 54 | *a = *a_reg;
|
---|
| 55 | *peak = *peak_reg;
|
---|
| 56 | *is_min = *flag2_reg;
|
---|
| 57 | *is_max = *flag1_reg;
|
---|
| 58 |
|
---|
| 59 | tmp1_next = tap[index3] + (tap[index2] << 1) + tap[index2];
|
---|
| 60 | tmp2_next = (tap[index1] << 1) + tap[index1] + tap[0];
|
---|
| 61 |
|
---|
| 62 | d_next = UWT_ZERO - *tmp1_reg + *tmp2_reg;
|
---|
| 63 | a_next = *tmp1_reg + *tmp2_reg;
|
---|
| 64 |
|
---|
| 65 | more_next = (*d_reg > UWT_ZERO);
|
---|
| 66 | less_next = (*d_reg < UWT_ZERO);
|
---|
| 67 |
|
---|
| 68 | peak_next = (tap[peak_index + 1] >> peak_shift);
|
---|
| 69 |
|
---|
| 70 | *flag2_reg = (*more_reg) && (!more_next);
|
---|
| 71 | *flag1_reg = (*less_reg) && (!less_next);
|
---|
| 72 |
|
---|
| 73 | *d_reg = d_next;
|
---|
| 74 | *a_reg = a_next;
|
---|
| 75 | *peak_reg = peak_next;
|
---|
| 76 |
|
---|
| 77 | *tmp1_reg = tmp1_next;
|
---|
| 78 | *tmp2_reg = tmp2_next;
|
---|
| 79 | *less_reg = less_next;
|
---|
| 80 | *more_reg = more_next;
|
---|
| 81 |
|
---|
| 82 |
|
---|
| 83 | /*
|
---|
| 84 | *d = UWT_ZERO - (tap[index3])
|
---|
| 85 | - (tap[index2] << 1) - tap[index2]
|
---|
| 86 | + (tap[index1] << 1) + tap[index1]
|
---|
| 87 | + (tap[0]);
|
---|
| 88 |
|
---|
| 89 | *a = (tap[index3])
|
---|
| 90 | + (tap[index2] << 1) + tap[index2]
|
---|
| 91 | + (tap[index1] << 1) + tap[index1]
|
---|
| 92 | + (tap[0]);
|
---|
| 93 |
|
---|
| 94 | *peak = (tap[peak_index] >> peak_shift);
|
---|
| 95 |
|
---|
| 96 | *is_min = (*d_reg < UWT_ZERO) && (*d >= UWT_ZERO) ? 1 : 0;
|
---|
| 97 | *is_max = (*d_reg > UWT_ZERO) && (*d <= UWT_ZERO) ? 1 : 0;
|
---|
| 98 | */
|
---|
| 99 | /*
|
---|
| 100 | if(((*is_min) || (*is_max)) && (level == 3)) printf("peak -> %d -> %d -> %d\n", (*peak), (*d_reg), (*d));
|
---|
| 101 | */
|
---|
| 102 | /*
|
---|
| 103 | *d_reg = *d;
|
---|
| 104 | */
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 | /* ----------------------------------------------------------------- */
|
---|
| 108 |
|
---|
| 109 | static void uwt_process(int *input, int *noise, int *peak, int *is_min, int *is_max, int *is_valid, int n)
|
---|
| 110 | {
|
---|
| 111 | int i, j, k;
|
---|
| 112 | int sample;
|
---|
| 113 |
|
---|
| 114 | int mode = 0;
|
---|
| 115 |
|
---|
| 116 | int time_from_start = 0;
|
---|
| 117 | int time_from_min = 0;
|
---|
| 118 | int time_from_max = 0;
|
---|
| 119 |
|
---|
| 120 | int noise_average = 0;
|
---|
| 121 |
|
---|
| 122 | int noise_buffer[UWT_NOISE_BUFFER_SIZE];
|
---|
| 123 |
|
---|
| 124 | int pulse_height = 0;
|
---|
| 125 |
|
---|
| 126 | int size;
|
---|
| 127 | int d_reg[UWT_LEVEL];
|
---|
| 128 | int a_reg[UWT_LEVEL], peak_reg[UWT_LEVEL];
|
---|
| 129 | int tmp1_reg[UWT_LEVEL], tmp2_reg[UWT_LEVEL];
|
---|
| 130 | int flag1_reg[UWT_LEVEL], flag2_reg[UWT_LEVEL];
|
---|
| 131 | int less_reg[UWT_LEVEL], more_reg[UWT_LEVEL];
|
---|
| 132 | int a, d;
|
---|
| 133 | int *tap[UWT_LEVEL];
|
---|
| 134 |
|
---|
| 135 | for(j = 0; j < UWT_NOISE_BUFFER_SIZE; ++j)
|
---|
| 136 | {
|
---|
| 137 | noise_buffer[j] = 0;
|
---|
| 138 | }
|
---|
| 139 |
|
---|
| 140 | // Tapped delay line
|
---|
| 141 | for(j = 0; j < UWT_LEVEL; ++j)
|
---|
| 142 | {
|
---|
| 143 | size = ((3 << j) + 1)*sizeof(int);
|
---|
| 144 | printf("%d -> %d\n", j+1, ((3 << j) + 1));
|
---|
| 145 | fflush(stdout);
|
---|
| 146 | tap[j] = (int *) malloc(size);
|
---|
| 147 | memset(tap[j], 0, size);
|
---|
| 148 | d_reg[j] = UWT_ZERO;
|
---|
| 149 | a_reg[j] = UWT_ZERO;
|
---|
| 150 | peak_reg[j] = UWT_ZERO;
|
---|
| 151 | tmp1_reg[j] = UWT_ZERO;
|
---|
| 152 | tmp2_reg[j] = UWT_ZERO;
|
---|
| 153 | flag1_reg[j] = UWT_ZERO;
|
---|
| 154 | flag2_reg[j] = UWT_ZERO;
|
---|
| 155 | less_reg[j] = UWT_ZERO;
|
---|
| 156 | more_reg[j] = UWT_ZERO;
|
---|
| 157 | }
|
---|
| 158 |
|
---|
| 159 | for(i = 0; i < n; ++i)
|
---|
| 160 | {
|
---|
| 161 | sample = input[i];
|
---|
| 162 | is_valid[i] = 0;
|
---|
| 163 |
|
---|
| 164 | for(j = 0; j < UWT_LEVEL; ++j)
|
---|
| 165 | {
|
---|
| 166 | uwt_bior31_step(sample, tap[j],
|
---|
| 167 | d_reg+j, a_reg+j, peak_reg+j, tmp1_reg+j, tmp2_reg+j, flag1_reg+j, flag2_reg+j, less_reg+j, more_reg+j,
|
---|
| 168 | &d, &a, peak+i, is_min+i, is_max+i, j+1);
|
---|
| 169 | sample = a;
|
---|
| 170 | }
|
---|
| 171 |
|
---|
| 172 | if(is_min[i] && mode > 0)
|
---|
| 173 | {
|
---|
| 174 | for(j = 0; j < UWT_NOISE_BUFFER_SIZE - 1; ++j)
|
---|
| 175 | {
|
---|
| 176 | noise_buffer[j] = noise_buffer[j+1] + peak[i];
|
---|
| 177 | }
|
---|
| 178 | noise_buffer[UWT_NOISE_BUFFER_SIZE-1] = peak[i];
|
---|
| 179 |
|
---|
| 180 | noise_average = noise_buffer[0] >> UWT_NOISE_BUFFER_SIZE_LOG2;
|
---|
| 181 |
|
---|
| 182 | time_from_min = 0;
|
---|
| 183 | }
|
---|
| 184 |
|
---|
| 185 | noise[i] = noise_average;
|
---|
| 186 |
|
---|
| 187 | switch(mode)
|
---|
| 188 | {
|
---|
| 189 | case 0:
|
---|
| 190 | ++time_from_start;
|
---|
| 191 |
|
---|
| 192 | if(time_from_start >= UWT_TYPICAL_START_TIME)
|
---|
| 193 | {
|
---|
| 194 | mode = 1;
|
---|
| 195 | time_from_start = 0;
|
---|
| 196 | }
|
---|
| 197 | break;
|
---|
| 198 |
|
---|
| 199 | case 1:
|
---|
| 200 | if(is_min[i]) ++time_from_start;
|
---|
| 201 |
|
---|
| 202 | if(time_from_start >= UWT_TYPICAL_NOISE_TIME)
|
---|
| 203 | {
|
---|
| 204 | mode = 2;
|
---|
| 205 | time_from_start = 0;
|
---|
| 206 | }
|
---|
| 207 | break;
|
---|
| 208 |
|
---|
| 209 | case 2:
|
---|
| 210 | if(is_max[i])
|
---|
| 211 | {
|
---|
| 212 | pulse_height = peak[i] - noise_average;
|
---|
| 213 |
|
---|
| 214 | if(pulse_height > UWT_SIGNAL_THRESHOLD)
|
---|
| 215 | {
|
---|
| 216 | printf("%d -> %d -> %d\n", pulse_height, time_from_min, time_from_max);
|
---|
| 217 | if(time_from_min < UWT_MAX_RISE_TIME &&
|
---|
| 218 | time_from_max > UWT_MIN_PEAK_DIST
|
---|
| 219 | )
|
---|
| 220 | {
|
---|
| 221 | is_valid[i] = 1;
|
---|
| 222 | }
|
---|
| 223 | time_from_max = 0;
|
---|
| 224 | }
|
---|
| 225 | }
|
---|
| 226 |
|
---|
| 227 | ++time_from_min;
|
---|
| 228 | ++time_from_max;
|
---|
| 229 |
|
---|
| 230 | break;
|
---|
| 231 |
|
---|
| 232 | default:
|
---|
| 233 | /* Do nothing */
|
---|
| 234 | break;
|
---|
| 235 | }
|
---|
| 236 | }
|
---|
| 237 |
|
---|
| 238 | for(j = 0; j < UWT_LEVEL; ++j)
|
---|
| 239 | {
|
---|
| 240 | free(tap[j]);
|
---|
| 241 | }
|
---|
| 242 |
|
---|
| 243 | }
|
---|
| 244 |
|
---|
| 245 | /* ----------------------------------------------------------------- */
|
---|
| 246 | /* Peak detection using "snake" algorithm */
|
---|
| 247 | /* ----------------------------------------------------------------- */
|
---|
| 248 |
|
---|
| 249 | /* Memory requirements */
|
---|
| 250 | /* noise buffer: 32 registers */
|
---|
| 251 | /* peak buffer: 7 registers */
|
---|
| 252 |
|
---|
| 253 | static void sum8(int *input, int *output, int n)
|
---|
| 254 | {
|
---|
| 255 | int i, j;
|
---|
| 256 |
|
---|
| 257 | // Tapped delay line
|
---|
| 258 | int *tap = (int *) malloc(8*sizeof(int));
|
---|
| 259 | memset(tap, 0, 8*sizeof(int));
|
---|
| 260 |
|
---|
| 261 | for(i = 0; i < n; ++i)
|
---|
| 262 | {
|
---|
| 263 | // Tapped delay line: shift one
|
---|
| 264 | for(j = 7; j > 0; --j)
|
---|
| 265 | {
|
---|
| 266 | tap[j] = tap[j-1];
|
---|
| 267 | }
|
---|
| 268 |
|
---|
| 269 | // Input in register 0
|
---|
| 270 | tap[0] = input[i];
|
---|
| 271 |
|
---|
| 272 | output[i] = 0;
|
---|
| 273 |
|
---|
| 274 | for(j = 0; j < 8; ++j)
|
---|
| 275 | {
|
---|
| 276 | output[i] += tap[j];
|
---|
| 277 | }
|
---|
| 278 |
|
---|
| 279 | output[i] = output[i] >> 3;
|
---|
| 280 |
|
---|
| 281 | }
|
---|
| 282 |
|
---|
| 283 | free(tap);
|
---|
| 284 | }
|
---|
| 285 |
|
---|
| 286 | /* ----------------------------------------------------------------- */
|
---|
| 287 |
|
---|
| 288 | #define PEAK_BUFFER_SIZE 7
|
---|
| 289 | #define NOISE_BUFFER_SIZE 32
|
---|
| 290 | #define NOISE_BUFFER_SIZE_LOG2 5
|
---|
| 291 |
|
---|
| 292 | #define TYPICAL_START_TIME 64
|
---|
| 293 | #define TYPICAL_RISE_TIME 12
|
---|
| 294 | #define TYPICAL_PILEUP_TIME 20
|
---|
| 295 |
|
---|
| 296 | #define SIGNAL_THRESHOLD 10
|
---|
| 297 |
|
---|
| 298 | static void csr_process(int *input, int *noise, int *peak, int *is_max, int n)
|
---|
| 299 | {
|
---|
| 300 | int i, j, k;
|
---|
| 301 | int sample;
|
---|
| 302 |
|
---|
| 303 |
|
---|
| 304 | int mode = 0;
|
---|
| 305 | int min_sample = 4095;
|
---|
| 306 |
|
---|
| 307 | int time_from_start = 0;
|
---|
| 308 | int time_from_min = 0;
|
---|
| 309 | int time_from_peak = 0;
|
---|
| 310 |
|
---|
| 311 | int noise_average = 0;
|
---|
| 312 | int min_noise_average = 4095;
|
---|
| 313 |
|
---|
| 314 | int noise_buffer[NOISE_BUFFER_SIZE];
|
---|
| 315 | int peak_buffer[PEAK_BUFFER_SIZE];
|
---|
| 316 |
|
---|
| 317 | int peak_value = 0;
|
---|
| 318 | int pulse_height = 0;
|
---|
| 319 |
|
---|
| 320 | int is_raising, is_stable, is_stored, is_valid, is_pileup;
|
---|
| 321 |
|
---|
| 322 | for(j = 0; j < NOISE_BUFFER_SIZE; ++j)
|
---|
| 323 | {
|
---|
| 324 | noise_buffer[j] = 4095;
|
---|
| 325 | }
|
---|
| 326 |
|
---|
| 327 | for(i = 0; i < n; ++i)
|
---|
| 328 | {
|
---|
| 329 | sample = input[i];
|
---|
| 330 | noise[i] = 0;
|
---|
| 331 | peak[i] = 0;
|
---|
| 332 | is_max[i] = 0;
|
---|
| 333 |
|
---|
| 334 | if(mode == 0 || mode == 1)
|
---|
| 335 | {
|
---|
| 336 | for(j = 0; j < NOISE_BUFFER_SIZE - 1; ++j)
|
---|
| 337 | {
|
---|
| 338 | noise_buffer[j] = noise_buffer[j+1];
|
---|
| 339 | }
|
---|
| 340 | noise_buffer[NOISE_BUFFER_SIZE-1] = sample;
|
---|
| 341 |
|
---|
| 342 | noise_average = 0;
|
---|
| 343 | for(j = 0; j < NOISE_BUFFER_SIZE; ++j)
|
---|
| 344 | {
|
---|
| 345 | noise_average += noise_buffer[j];
|
---|
| 346 | }
|
---|
| 347 | noise_average = noise_average >> NOISE_BUFFER_SIZE_LOG2;
|
---|
| 348 | }
|
---|
| 349 |
|
---|
| 350 | noise[i] = noise_average;
|
---|
| 351 |
|
---|
| 352 | for(j = 0; j < PEAK_BUFFER_SIZE - 1; ++j)
|
---|
| 353 | {
|
---|
| 354 | peak_buffer[j] = peak_buffer[j+1];
|
---|
| 355 | }
|
---|
| 356 | peak_buffer[PEAK_BUFFER_SIZE-1] = sample;
|
---|
| 357 |
|
---|
| 358 | switch(mode)
|
---|
| 359 | {
|
---|
| 360 | case 0:
|
---|
| 361 | if(noise_average < min_noise_average)
|
---|
| 362 | {
|
---|
| 363 | min_noise_average = noise_average;
|
---|
| 364 | }
|
---|
| 365 |
|
---|
| 366 | ++time_from_start;
|
---|
| 367 |
|
---|
| 368 | if(time_from_start >= TYPICAL_START_TIME)
|
---|
| 369 | {
|
---|
| 370 | mode = 1;
|
---|
| 371 | noise_average = min_noise_average;
|
---|
| 372 | for(j = 0; j < NOISE_BUFFER_SIZE; ++j)
|
---|
| 373 | {
|
---|
| 374 | noise_buffer[j] = min_noise_average;
|
---|
| 375 | }
|
---|
| 376 | }
|
---|
| 377 | break;
|
---|
| 378 |
|
---|
| 379 | case 1:
|
---|
| 380 | is_raising = 0;
|
---|
| 381 | is_stable = 0;
|
---|
| 382 | if(sample >= min_sample)
|
---|
| 383 | {
|
---|
| 384 | is_stable = 1;
|
---|
| 385 | }
|
---|
| 386 | else
|
---|
| 387 | {
|
---|
| 388 | min_sample = sample;
|
---|
| 389 | }
|
---|
| 390 | if(peak_buffer[0] < peak_buffer[3]) is_raising = 1;
|
---|
| 391 | if(is_stable && is_raising)
|
---|
| 392 | {
|
---|
| 393 | ++time_from_min;
|
---|
| 394 | }
|
---|
| 395 | else
|
---|
| 396 | {
|
---|
| 397 | time_from_min = 0;
|
---|
| 398 | if(!is_raising) min_sample = peak_buffer[3];
|
---|
| 399 | }
|
---|
| 400 | if(time_from_min >= TYPICAL_RISE_TIME)
|
---|
| 401 | {
|
---|
| 402 | mode = 2;
|
---|
| 403 | is_stored = 0;
|
---|
| 404 | is_valid = 0;
|
---|
| 405 | }
|
---|
| 406 | break;
|
---|
| 407 |
|
---|
| 408 | case 2:
|
---|
| 409 | if(!is_stored)
|
---|
| 410 | {
|
---|
| 411 | if(peak_buffer[3] > peak_buffer[0] &&
|
---|
| 412 | peak_buffer[3] > peak_buffer[6] &&
|
---|
| 413 | peak_buffer[3] >= peak_buffer[2] &&
|
---|
| 414 | peak_buffer[3] >= peak_buffer[4])
|
---|
| 415 | {
|
---|
| 416 | peak_value = peak_buffer[3];
|
---|
| 417 | time_from_peak = 3;
|
---|
| 418 | pulse_height = peak_value - noise_average;
|
---|
| 419 | if(pulse_height > SIGNAL_THRESHOLD)
|
---|
| 420 | {
|
---|
| 421 | is_valid = 1;
|
---|
| 422 | peak[i] = peak_value;
|
---|
| 423 | is_max[i] = 1;
|
---|
| 424 | is_stored = 1;
|
---|
| 425 | }
|
---|
| 426 | mode = 3;
|
---|
| 427 | }
|
---|
| 428 | }
|
---|
| 429 | ++time_from_min;
|
---|
| 430 | is_pileup = 0;
|
---|
| 431 | break;
|
---|
| 432 |
|
---|
| 433 | case 3:
|
---|
| 434 | ++time_from_min;
|
---|
| 435 | ++time_from_peak;
|
---|
| 436 | if(time_from_min > TYPICAL_PILEUP_TIME ||
|
---|
| 437 | time_from_peak > TYPICAL_PILEUP_TIME)
|
---|
| 438 | {
|
---|
| 439 | is_pileup = 1;
|
---|
| 440 | }
|
---|
| 441 | if(peak_buffer[3] < peak_buffer[0] &&
|
---|
| 442 | peak_buffer[3] < peak_buffer[6] &&
|
---|
| 443 | peak_buffer[3] <= peak_buffer[2] &&
|
---|
| 444 | peak_buffer[3] <= peak_buffer[4])
|
---|
| 445 | {
|
---|
| 446 | min_sample = peak_buffer[3];
|
---|
| 447 | mode = 1;
|
---|
| 448 | }
|
---|
| 449 | break;
|
---|
| 450 |
|
---|
| 451 | default:
|
---|
| 452 | /* Do nothing */
|
---|
| 453 | break;
|
---|
| 454 | }
|
---|
| 455 | }
|
---|
| 456 | }
|
---|
| 457 |
|
---|
| 458 | /* ----------------------------------------------------------------- */
|
---|
| 459 | /* Interface with Tcl */
|
---|
| 460 | /* ----------------------------------------------------------------- */
|
---|
| 461 |
|
---|
| 462 | static int UwtProcessObjCmdProc(ClientData clientData, Tcl_Interp *interp,
|
---|
| 463 | int objc, Tcl_Obj *CONST objv[])
|
---|
| 464 | {
|
---|
| 465 | int size = 0;
|
---|
| 466 | int i = 0;
|
---|
| 467 | int level = 0;
|
---|
| 468 | double value = 0.0;
|
---|
| 469 | int *input, *noise, *peak, *is_min, *is_max, *is_valid;
|
---|
| 470 | Tcl_Obj *result = NULL;
|
---|
| 471 | Tcl_Obj *listnoise = NULL;
|
---|
| 472 | Tcl_Obj *listpeak = NULL;
|
---|
| 473 | Tcl_Obj *listmin = NULL;
|
---|
| 474 | Tcl_Obj *listmax = NULL;
|
---|
| 475 | Tcl_Obj *listvalid = NULL;
|
---|
| 476 |
|
---|
| 477 | if(objc != 2)
|
---|
| 478 | {
|
---|
| 479 | Tcl_WrongNumArgs(interp, 1, objv, "data");
|
---|
| 480 | return TCL_ERROR;
|
---|
| 481 | }
|
---|
| 482 |
|
---|
| 483 | if(TCL_OK != Tcl_ListObjLength(interp, objv[1], &size))
|
---|
| 484 | {
|
---|
| 485 | return TCL_ERROR;
|
---|
| 486 | }
|
---|
| 487 |
|
---|
| 488 | input = (int *) malloc(size*sizeof(int));
|
---|
| 489 | noise = (int *) malloc(size*sizeof(int));
|
---|
| 490 | peak = (int *) malloc(size*sizeof(int));
|
---|
| 491 | is_min = (int *) malloc(size*sizeof(int));
|
---|
| 492 | is_max = (int *) malloc(size*sizeof(int));
|
---|
| 493 | is_valid = (int *) malloc(size*sizeof(int));
|
---|
| 494 |
|
---|
| 495 | for(i = 0; i < size; ++i)
|
---|
| 496 | {
|
---|
| 497 | Tcl_ListObjIndex(interp, objv[1], i, &result);
|
---|
| 498 | if(TCL_OK != Tcl_GetDoubleFromObj(interp, result, &value))
|
---|
| 499 | {
|
---|
| 500 | free(input);
|
---|
| 501 | free(noise);
|
---|
| 502 | free(peak);
|
---|
| 503 | free(is_min);
|
---|
| 504 | free(is_max);
|
---|
| 505 | free(is_valid);
|
---|
| 506 | return TCL_ERROR;
|
---|
| 507 | }
|
---|
| 508 | input[i] = (int) value;
|
---|
| 509 | /*
|
---|
| 510 | printf("%d -> %g\n", i, input[i]);
|
---|
| 511 | */
|
---|
| 512 | }
|
---|
| 513 |
|
---|
| 514 | uwt_process(input, noise, peak, is_min, is_max, is_valid, size);
|
---|
| 515 |
|
---|
| 516 | result = Tcl_GetObjResult(interp);
|
---|
| 517 | listnoise = Tcl_NewObj();
|
---|
| 518 | listpeak = Tcl_NewObj();
|
---|
| 519 | listmin = Tcl_NewObj();
|
---|
| 520 | listmax = Tcl_NewObj();
|
---|
| 521 | listvalid = Tcl_NewObj();
|
---|
| 522 | for(i = 0; i < size; ++i)
|
---|
| 523 | {
|
---|
| 524 | Tcl_ListObjAppendElement(interp, listnoise, Tcl_NewIntObj(noise[i]));
|
---|
| 525 | Tcl_ListObjAppendElement(interp, listpeak, Tcl_NewIntObj(peak[i]));
|
---|
| 526 | Tcl_ListObjAppendElement(interp, listmin, Tcl_NewIntObj(is_min[i]*peak[i]));
|
---|
| 527 | Tcl_ListObjAppendElement(interp, listmax, Tcl_NewIntObj(is_max[i]*peak[i]));
|
---|
| 528 | Tcl_ListObjAppendElement(interp, listvalid, Tcl_NewIntObj(is_valid[i]*peak[i]));
|
---|
| 529 | }
|
---|
| 530 |
|
---|
| 531 | Tcl_ListObjAppendElement(interp, result, listnoise);
|
---|
| 532 | Tcl_ListObjAppendElement(interp, result, listpeak);
|
---|
| 533 | Tcl_ListObjAppendElement(interp, result, listmin);
|
---|
| 534 | Tcl_ListObjAppendElement(interp, result, listmax);
|
---|
| 535 | Tcl_ListObjAppendElement(interp, result, listvalid);
|
---|
| 536 |
|
---|
| 537 | free(input);
|
---|
| 538 | free(noise);
|
---|
| 539 | free(peak);
|
---|
| 540 | free(is_min);
|
---|
| 541 | free(is_max);
|
---|
| 542 | free(is_valid);
|
---|
| 543 |
|
---|
| 544 | return TCL_OK;
|
---|
| 545 | }
|
---|
| 546 |
|
---|
| 547 | /* ----------------------------------------------------------------- */
|
---|
| 548 |
|
---|
| 549 | static int Sum8ObjCmdProc(ClientData clientData, Tcl_Interp *interp,
|
---|
| 550 | int objc, Tcl_Obj *CONST objv[])
|
---|
| 551 | {
|
---|
| 552 | int size = 0;
|
---|
| 553 | int i = 0;
|
---|
| 554 | int level = 0;
|
---|
| 555 | double value = 0.0;
|
---|
| 556 | int *input, *output;
|
---|
| 557 | Tcl_Obj *result = NULL;
|
---|
| 558 |
|
---|
| 559 | if(objc != 2)
|
---|
| 560 | {
|
---|
| 561 | Tcl_WrongNumArgs(interp, 1, objv, "data");
|
---|
| 562 | return TCL_ERROR;
|
---|
| 563 | }
|
---|
| 564 |
|
---|
| 565 | if(TCL_OK != Tcl_ListObjLength(interp, objv[1], &size))
|
---|
| 566 | {
|
---|
| 567 | return TCL_ERROR;
|
---|
| 568 | }
|
---|
| 569 |
|
---|
| 570 | input = (int *) malloc(size*sizeof(int));
|
---|
| 571 | output = (int *) malloc(size*sizeof(int));
|
---|
| 572 |
|
---|
| 573 | for(i = 0; i < size; ++i)
|
---|
| 574 | {
|
---|
| 575 | Tcl_ListObjIndex(interp, objv[1], i, &result);
|
---|
| 576 | if(TCL_OK != Tcl_GetDoubleFromObj(interp, result, &value))
|
---|
| 577 | {
|
---|
| 578 | free(input);
|
---|
| 579 | free(output);
|
---|
| 580 | return TCL_ERROR;
|
---|
| 581 | }
|
---|
| 582 | input[i] = (int) value;
|
---|
| 583 | /*
|
---|
| 584 | printf("%d -> %g\n", i, input[i]);
|
---|
| 585 | */
|
---|
| 586 | }
|
---|
| 587 |
|
---|
| 588 | sum8(input, output, size);
|
---|
| 589 |
|
---|
| 590 | result = Tcl_GetObjResult(interp);
|
---|
| 591 | for(i = 0; i < size; ++i)
|
---|
| 592 | {
|
---|
| 593 | Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(output[i]));
|
---|
| 594 | /*
|
---|
| 595 | printf("%d -> %g\n", i, d[i]);
|
---|
| 596 | */
|
---|
| 597 | }
|
---|
| 598 |
|
---|
| 599 | free(input);
|
---|
| 600 | free(output);
|
---|
| 601 |
|
---|
| 602 | return TCL_OK;
|
---|
| 603 | }
|
---|
| 604 |
|
---|
| 605 | /* ----------------------------------------------------------------- */
|
---|
| 606 |
|
---|
| 607 | static int CsrProcessObjCmdProc(ClientData clientData, Tcl_Interp *interp,
|
---|
| 608 | int objc, Tcl_Obj *CONST objv[])
|
---|
| 609 | {
|
---|
| 610 | int size = 0;
|
---|
| 611 | int i = 0;
|
---|
| 612 | int level = 0;
|
---|
| 613 | double value = 0.0;
|
---|
| 614 | int *input, *noise, *peak, *is_max;
|
---|
| 615 | Tcl_Obj *result = NULL;
|
---|
| 616 | Tcl_Obj *listnoise = NULL;
|
---|
| 617 | Tcl_Obj *listpeak = NULL;
|
---|
| 618 | Tcl_Obj *listmax = NULL;
|
---|
| 619 |
|
---|
| 620 | if(objc != 2)
|
---|
| 621 | {
|
---|
| 622 | Tcl_WrongNumArgs(interp, 1, objv, "data");
|
---|
| 623 | return TCL_ERROR;
|
---|
| 624 | }
|
---|
| 625 |
|
---|
| 626 | if(TCL_OK != Tcl_ListObjLength(interp, objv[1], &size))
|
---|
| 627 | {
|
---|
| 628 | return TCL_ERROR;
|
---|
| 629 | }
|
---|
| 630 |
|
---|
| 631 | input = (int *) malloc(size*sizeof(int));
|
---|
| 632 | noise = (int *) malloc(size*sizeof(int));
|
---|
| 633 | peak = (int *) malloc(size*sizeof(int));
|
---|
| 634 | is_max = (int *) malloc(size*sizeof(int));
|
---|
| 635 |
|
---|
| 636 | for(i = 0; i < size; ++i)
|
---|
| 637 | {
|
---|
| 638 | Tcl_ListObjIndex(interp, objv[1], i, &result);
|
---|
| 639 | if(TCL_OK != Tcl_GetDoubleFromObj(interp, result, &value))
|
---|
| 640 | {
|
---|
| 641 | free(input);
|
---|
| 642 | free(noise);
|
---|
| 643 | free(peak);
|
---|
| 644 | free(is_max);
|
---|
| 645 | return TCL_ERROR;
|
---|
| 646 | }
|
---|
| 647 | input[i] = (int) value;
|
---|
| 648 | /*
|
---|
| 649 | printf("%d -> %g\n", i, input[i]);
|
---|
| 650 | */
|
---|
| 651 | }
|
---|
| 652 |
|
---|
| 653 | csr_process(input, noise, peak, is_max, size);
|
---|
| 654 |
|
---|
| 655 | result = Tcl_GetObjResult(interp);
|
---|
| 656 | listnoise = Tcl_NewObj();
|
---|
| 657 | listpeak = Tcl_NewObj();
|
---|
| 658 | listmax = Tcl_NewObj();
|
---|
| 659 | for(i = 0; i < size; ++i)
|
---|
| 660 | {
|
---|
| 661 | Tcl_ListObjAppendElement(interp, listnoise, Tcl_NewIntObj(noise[i]));
|
---|
| 662 | Tcl_ListObjAppendElement(interp, listpeak, Tcl_NewIntObj(peak[i]));
|
---|
| 663 | Tcl_ListObjAppendElement(interp, listmax, Tcl_NewIntObj(is_max[i]));
|
---|
| 664 | }
|
---|
| 665 |
|
---|
| 666 | Tcl_ListObjAppendElement(interp, result, listnoise);
|
---|
| 667 | Tcl_ListObjAppendElement(interp, result, listpeak);
|
---|
| 668 | Tcl_ListObjAppendElement(interp, result, listmax);
|
---|
| 669 |
|
---|
| 670 | free(input);
|
---|
| 671 | free(noise);
|
---|
| 672 | free(peak);
|
---|
| 673 | free(is_max);
|
---|
| 674 |
|
---|
| 675 | return TCL_OK;
|
---|
| 676 | }
|
---|
| 677 |
|
---|
| 678 | /* ----------------------------------------------------------------- */
|
---|
| 679 |
|
---|
| 680 | int Csr_Init(Tcl_Interp *interp)
|
---|
| 681 | {
|
---|
| 682 | Tcl_CreateObjCommand(interp, "csr_uwt_process", UwtProcessObjCmdProc, 0, 0);
|
---|
| 683 | Tcl_CreateObjCommand(interp, "csr_sum8", Sum8ObjCmdProc, 0, 0);
|
---|
| 684 | Tcl_CreateObjCommand(interp, "csr_process", CsrProcessObjCmdProc, 0, 0);
|
---|
| 685 |
|
---|
| 686 | return Tcl_PkgProvide(interp, "csr", "0.1");
|
---|
| 687 | }
|
---|
| 688 |
|
---|