text: #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <time.h>
  #include <math.h>
  #include <assert.h>
  
  // User defined libraries
  #include "equalstrings.h"
  
  #define TRUE 1
  #define FALSE 0
  
  #define HEADER_SIZE 13
  
  // Program to interpolate and add GNUPLOT format periodograms generated by FFANCY
  // Written by Andrew Cameron
  // Version 0.2 - Last updated 11/09/2016
  
  /*
  
  CHANGELOG:
  - v0.2 - Updated the help menu for publication
  
  */
  
  // ***** FUNCTION PROTOTYPES *****
  
  // prints out an explanation of how to use the command line interface
  void help();
  
  // strips the header from a file
  void header_strip(FILE* file);
  
  // copies the header from one file into another file
  void header_copy(FILE *infile, FILE *outfile);
  
  // determines the number of data-containing lines in a file
  int data_lines(FILE *file);
  
  // reads a file into the sample and data arrays
  void array_reader(FILE *file, double *sample_array, double *data_array, int size);
  
  // ***** MAIN FUNCTION *****
  
  int main(int argc, char** argv) {
  
    // declare variables and initialise with defaults
    FILE *inputfile1 = NULL;
    FILE *inputfile2 = NULL;
    FILE *outputfile = NULL;
  
    int ii; // counter
  
    // check that a valid number of arguments have been passed
    if (argc < 2) {
      help();
      exit(0);
    }
  
    // scan arguments and allocate variables
    if (argc > 1) {
      ii=1;
      while (ii < argc) {
        if (equal_strings(argv[ii],"-f1")) {
  	ii++;
          inputfile1 = fopen(argv[ii], "r");
        } else if (equal_strings(argv[ii],"-f2")) {
  	ii++;
  	inputfile2 = fopen(argv[ii], "r");
        } else if (equal_strings(argv[ii],"-o")) {
  	ii++;
  	outputfile = fopen(argv[ii], "w+");
        } else if (equal_strings(argv[ii], "-h") || equal_strings(argv[ii], "--help")) {
  	help();
  	exit(0);
        } else {
  	printf("Unknown argument (%s) passed to program.\nUse -h / --help to display help menu with acceptable arguments.\n",argv[ii]);
  	exit(0);
        }
        ii++;
      }
    }
  
    // test for valid input
    assert(inputfile1 != NULL);
    assert(inputfile2 != NULL);
    assert(outputfile != NULL);
  
    // get size of the two input files
    int file1_size = data_lines(inputfile1);
    int file2_size = data_lines(inputfile2);
    printf("Size of file 1 is %d lines | Size of file 2 is %d lines.\n", file1_size, file2_size);
  
    // allocate sample and data arrays
    double* sample_array1 = (double*)malloc(sizeof(double) * file1_size);
    double* data_array1 = (double*)malloc(sizeof(double) * file1_size);
  
    double* sample_array2 = (double*)malloc(sizeof(double) * file2_size);
    double* data_array2 = (double*)malloc(sizeof(double) * file2_size);
    printf("Arrays allocated.\n");
  
    // read into the arrays
    array_reader(inputfile1, sample_array1, data_array1, file1_size);
    array_reader(inputfile2, sample_array2, data_array2, file2_size);
    printf("Arrays initialised with values.\n");
  
    // copy the header of one file into the output file
    // header_copy(inputfile1, outputfile);
    // printf("Header copied to output file.\n");
  
    // PREPARATION COMPLETE
    // can now close out the input files
    fclose(inputfile1);
    fclose(inputfile2);
  
    // Now comes the main body of the program, scrolling through both array pairs and interpolating as needed, then writing out to the final file
    // set starting counters for both array sets
    int counter1 = 0;
    int counter2 = 0;
  
    // determine which array has the earlier starting period, and scroll it forward until it is equal to or greater than the starting period of the other
    printf("Winding arrays into position for addition...\n");
  
    if (sample_array1[counter1] < sample_array2[counter2]) {
      // wind counter1 forward
      while(sample_array1[counter1] < sample_array2[counter2]) {
        counter1++;
      }
    } else if (sample_array1[counter1] > sample_array2[counter2]) {
      // wind counter 2 forward
      while(sample_array1[counter1] > sample_array2[counter2]) {
        counter2++;
      }
    }
  
    printf("Initial winding complete.\n");
  
    // we have now reached a region which is common to both periodograms
    // begin the addition algorithm
    while ((counter1 < file1_size) && (counter2 < file2_size)) {
    
        if (sample_array1[counter1] == sample_array2[counter2]) {
  
  	// the easy case - just add and write out
  	fprintf(outputfile, "%.10lf 0 0 %.10lf\n", sample_array1[counter1], data_array1[counter1] + data_array2[counter2]);
  	counter1++;
  	counter2++;
  	
        } else if (sample_array1[counter1] < sample_array2[counter2]) {
  
  	// need to interpolate a value in array 2 to add to the array 1 value
  	// accessing invalid earlier data should be elliminated by the earlier winding procedure
  
  	printf("Interpolating elements in second file...\n");
  
  	double interpolated_value = ((data_array2[counter2] - data_array2[counter2-1])/(sample_array2[counter2] - sample_array2[counter2-1]))*(sample_array1[counter1] - sample_array2[counter2 - 1]) + data_array2[counter2-1];
  
  	// write out to file
  	fprintf(outputfile, "%.10lf 0 0 %.10lf\n", sample_array1[counter1], interpolated_value + data_array1[counter1]);
  
  	// increment counter 1 only
  	counter1++;
  	
        } else if (sample_array1[counter1] > sample_array2[counter2]) {
  	
  	// need to interpolate a value in array 1 to add to the array 2 value
  	// accessing invalid earlier data should be elliminated by the earlier winding procedure
  
  	printf("Interpolating elements in first file...\n");
  
  	double interpolated_value = ((data_array1[counter1] - data_array1[counter1-1])/(sample_array1[counter1] - sample_array1[counter1-1]))*(sample_array2[counter2] - sample_array1[counter1 - 1]) + data_array1[counter1-1];
  
  	// write out to file
  	fprintf(outputfile, "%.10lf 0 0 %.10lf\n", sample_array2[counter2], interpolated_value + data_array2[counter2]);
  
  	// increment counter 2 only
  	counter2++;
  	
        }
    }
  
    printf("Addition complete.\n");
  
    // close the output file
    fclose(outputfile);
  
    // free allocated memory
    free(sample_array1);
    free(data_array1);
  
    free(sample_array2);
    free(data_array2);
  
    // program complete
    
    return 0;
    
  }
  
  // ***** FUNCTION BODIES *****
  
  void header_strip(FILE* file) {
  
    assert(file != NULL);
    
    // assumes a standard header size as defined by a constant
  
    int ii = 0;
    char buffer[100];
    while (ii < HEADER_SIZE) {
      fscanf(file, "%s", buffer);
      ii++;
    }
    
    return;
    
  }
  
  int data_lines(FILE *file) {
  
    assert(file != NULL);
  
    // go to start of file
    rewind(file);
  
    // strip header
    header_strip(file);
  
    // loop through lines and increment
    int ii = 0;
    double samples;
    int ds_factor;
    double ds_samples;
    double snr;
    while (fscanf(file, "%lf %d %lf %lf", &samples, &ds_factor, &ds_samples, &snr) != EOF) {
      // do nothing but increment
      ii++;
    }
  
    // reset file
    rewind(file);
    
    return ii;
    
  }
  
  void header_copy(FILE *infile, FILE *outfile) {
  
    assert(infile != NULL);
    assert(outfile != NULL);
  
    // assumes a standard header size as defined by a constant
  
    // rewind the infile
    rewind(infile);
  
    int ii = 0;
    char buffer[100];
    while (ii < HEADER_SIZE) {
      fscanf(infile, "%s", buffer);
      fprintf(outfile, "%s ", buffer);
      ii++;
    }
  
    // tidy up
    fprintf (outfile, "\n");
    
    return;
    
  }
  
  void array_reader(FILE *file, double *sample_array, double *data_array, int size) {
  
    assert(file != NULL);
    assert(sample_array != NULL);
    assert(data_array != NULL);
  
    // go to start of file
    rewind(file);
  
    // strip header
    header_strip(file);
  
    // loop through lines and increment
    int ii = 0;
    double samples;
    int ds_factor;
    double ds_samples;
    double snr;
    while ((fscanf(file, "%lf %d %lf %lf", &samples, &ds_factor, &ds_samples, &snr) != EOF) && (ii < size)) {
      // seed arrays
      sample_array[ii] = samples;
      data_array[ii] = snr;
      ii++;
    }
    
    return;
    
  }
  
  void help() {
  
    printf("\nADD_PERIODOGRAMS - Adds two GNUPLOT format periodograms as produced by FFAncy.\n");
    printf("Version 0.1, last updated 24/03/2016.\n");
    printf("Written by Andrew Cameron, MPIFR IMPRS PhD Student.\n");
    printf("\nProgram will only add two periodograms together over their region of common overlap in sample space.\n");
    printf("In the event that trial period values do not precisely coincide, different sets of period trials are\nadded together by interpolating between values in a given periodogram.\n");
    printf("\n*****\n\n");
    printf("Input options:\n");
  
    printf("\n----- File Input/Output -----\n");
    printf("-f1 [file]     Name of the first file to be added together.\n");
    printf("-f2 [file]     Name of the second file to be added together.\n");
    printf("-o [file]      Name of the output file.\n");
  
    printf("\n----- Miscellaneous -----\n");
    printf("-h / --help    Displays this useful and informative help menu.\n\n");
  
    return;
  
  }
  
  
  
  
  
  
  
  
  
  
  
  
  
  