For loop that looks at a certain window in an array

52 views Asked by At

The code is supposed to load in a CSV data file that has 50 rows and 3000 columns, each row is an EEG sleep signal. Each signal should be read separately and the event detection function should differentiate between an awake sleep state and a non-REM sleep state (NREM, non-rapid eye movement sleep). The data looks like a "U" shape with the awake state having higher values. The threshold is 0.00046 with anything above that being awake signals. We are also only observing the signal between the 500ms and 2500ms. If the threshold is triggered that signal should be saved as 1 and if not it's saved as a 2. The final result matrix should be 50 x 1.

//Event detection
void event_detection(double signal[], int result_matrix[], int length,
                     double threshold, int start_index, int end_index) {
    for (int i = start_index; i <= end_index; i++) {
        printf("%lf\n", signal[i]);  // Print for debugging

        // Assuming fft_result contains magnitudes of relevant frequencies
        if (signal[i] > threshold) {
            result_matrix[i] = 1;  // Awake
        } else {
            result_matrix[i] = 2;  // Non-REM sleep
        }
    } 
}
int main(int argc, char* argv[]) {

    FILE* file = fopen("EEG_SleepData_30sec_100Hz.csv", "r");
    if (file == NULL) {
        perror("Error opening file");
        return EXIT_FAILURE;
    }

    // Load the CSV file into a 2D array
    int num_signals = num_rows_in_file(file);
    int signal_length = num_cols_in_file(file);
    printf("Number of rows = %d  Number of columns = %d\n", num_signals, signal_length);

    rewind(file);

    double** signals = load_data(file, num_signals, signal_length);

    fclose(file);


     // Parameters for event detection
    double threshold = 0.00046;
    int start_index = 500;
    int end_index = 2500;

    // Open the CSV file for writing the result
    FILE* result_file = fopen("result_signal.csv", "w");
    if (result_file == NULL) {
        perror("Error opening result file");
        free_2d_array(signals, num_signals);
        return EXIT_FAILURE;
    }

 // Perform event detection
        int* result_matrix = (int*)malloc(signal_length * sizeof(int));
        if (result_matrix == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            return EXIT_FAILURE;
        }

        event_detection(fft_result, result_matrix, signal_length, threshold, start_index, end_index);

        // Write the result matrix to the result file
        for (int j = 0; j < (end_index - start_index + 1); j++) {
            fprintf(result_file, "%d\n", result_matrix[j]);
        }
    
    }

    fclose(result_file);
    free_2d_array(signals, num_signals);

    return 0;
}

This event detection function does not work the way I need it to. The for loop doesn't return the right data when I debugged it and that throws everything else off. I don't know how to fix it.

The result matrix currently looks like this

result matrix

while it should look like this

correct result matrix

1

There are 1 answers

1
Jonathan Leffler On

I think the trouble is that the loop really only records the status according to the last entry examined and that you're using i for two different purposes at once.

You probably need a test more like:

int high = 0;
for (int i = start_index; i <= end_index; i++) {
    printf("%lf\n", signal[i]);  // Print for debugging

    // Assuming fft_result contains magnitudes of relevant frequencies
    if (signal[i] > threshold) {
        high = 1;
        break;
    }
}
result_matrix[n] = high ? 1 : 2;

Since the row might have 3,000 columns and the result matrix only has 1 entry per row, you also need to separate i from the index in the result matrix — I used n in the code fragment.

Since you've not provided an MCVE (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example — the same idea by a different name), it's hard to be sure what goes on. And anything with 3,000 columns is too big to be minimal. But you could provide simplified data with, say, 10 columns and maybe 5 rows, and the result expected from that simplified sample data. It'll be easier for you to see what's going on — the full-size data sample would be intimidating to manually scrutinize.