Beispiel #1
0
 // Returns a new CubicSpline setting array lengths to n and all array values to zero with natural spline default
 // Primarily for use in BiCubicSpline
 public virtual CubicSpline zero(int n)
 {
     if (n < 3)
         throw new System.ArgumentException("A minimum of three data points is needed");
     CubicSpline aa = new CubicSpline(n);
     return aa;
 }
Beispiel #2
0
 // Create a one dimensional array of cubic spline objects of length n each of array length m
 // Primarily for use in BiCubicSpline
 public virtual CubicSpline[] oneDarray(int n, int m)
 {
     if (m < 3)
         throw new System.ArgumentException("A minimum of three data points is needed");
     CubicSpline[] a = new CubicSpline[n];
     for (int i = 0; i < n; i++)
     {
         a[i] = zero(m);
     }
     return a;
 }
Beispiel #3
0
        public static bool GenerateFeatureVector(double lastTimeStamp)
        {

            // Generate a feature vector only, if the next window end has
            // passed based on the configuration parameters (window size and overlap)
            // otherwise return false
            if (lastTimeStamp < Extractor.next_window_end)
                return false;

            // the last time stamp is more than the next expected window end
            // At this point, we have a complete window ready for feature calculation

            //compute the boundaries for the current window
            double window_start_time = lastTimeStamp - Extractor.dconfiguration.WindowTime;
            double window_end_time = lastTimeStamp;
            double current_time = window_end_time;
            //compute the end of the next overlapping window
            next_window_end = window_end_time + (Extractor.dconfiguration.WindowTime * Extractor.dconfiguration.WindowOverlap);

            #region sensors window grabbing and interpolation

            // Go through each sensor and extract the collected data within 
            // the current time window
            for (int j = 0; (j < Extractor.extractorSensorCount); j++)
            {

                // Check that the previous sensor in the loop did not report
                // deteriorated quality for its data
                #region sensors window quality
                if (isAcceptableLossRate == false)
                    break;

                // check if earlier axes reported excessive consecutive loss of data frames
                if (isAcceptableConsecutiveLoss == false)
                {
                    Extractor.discardedConsecutiveLossWindows++;
                    break;
                }
                #endregion sensors window quality

                // determine the base index for the current sensor in data array, each sensor has 4 rows (x,y,z,timestamp)
                int sensor_index = j * 4;
                int time_index = sensor_index + 3;

                // determine the last read data sample for the current sensor
                // by looking at its index
                int last_sample = 0;
                if (y_index[j] == 0)
                    last_sample = Extractor.EXPECTED_WINDOW_SIZES[j] - 1;
                else
                    last_sample = y_index[j] - 1;

                //              int total_data_points = 0, distinct_data_points = 0;
                int distinct_data_points = 0;

                //Grab the readings for each axis of a sensor and smoothen it
                #region sensor window grabbing and interpolation
                // Go through each axis of the current sensor and smooth
                // it using the cubic spline
                for (int axes_num = 0; (axes_num < 3); axes_num++)
                {

                    //calculate the exact index based on the 
                    // base sensor index and the axis number
                    int axes_index = sensor_index + axes_num;  //for data array
                    int interpolated_axes_index = j * 3 + axes_num; //for interpolated data array

                    // create 2 arrays to store x and y values for the cubic spline
                    // it is sufficient to have an array of expected sampling rate window size
                    // for 3 mites that would be 180/60
                    double[] xvals = new double[Extractor.EXPECTED_WINDOW_SIZES[j]];
                    double[] yvals = new double[Extractor.EXPECTED_WINDOW_SIZES[j]];

                    //point to the last sample that was read and get its time
                    int sample_index = last_sample;
                    current_time = data[time_index][sample_index];

                    //copy samples in the last time window
                    //                    total_data_points = 0;
                    distinct_data_points = 0;
                    //                    double previous_time = 0;
                    //Grab the values for a specific sensor axes between
                    //window start and window end
                    #region window grabbing
                    // Start going back from the current time (window end) till the start of the window
                    // without exceeding the expected sampling rate and fill in the data in the signal
                    // value for the axis in yvals and the relative time value from the window start
                    while ((current_time >= window_start_time) && (current_time <= window_end_time)
                         && (distinct_data_points < Extractor.EXPECTED_WINDOW_SIZES[j]))
                    {

                        //some time stamps from the mites are identical
                        // for interpolation that will cause an error
                        // simply take the first value for a time point and ignore the
                        // rest, another strategy would be to average over these values
                        //if (current_time == previous_time)
                        //{
                        //    //Get the time of the previous sample and skip the sample
                        //    if (sample_index == 0)
                        //        sample_index = EXPECTED_WINDOW_SIZE - 1;
                        //    else
                        //        sample_index--;
                        //    current_time = data[time_index][sample_index];
                        //    total_data_points++;
                        //    continue;
                        //}

                        // Quality Control
                        // check the time between consecutive data frames and make sure it does
                        // not exceed maximum_consecutive_loss, do not do that for the first
                        // entry of the window
                        // Not suitable for the phone due to time resolution
                        //if (distinct_data_points > 0)
                        //{
                        //    int consecutive_lost_packets = (int)((previous_time - current_time) / EXPECTED_SAMPLES_SPACING);
                        //    if (consecutive_lost_packets > Extractor.dconfiguration.MaximumConsecutiveFrameLoss)
                        //    {
                        //        Extractor.discardedConsecutiveLossWindows++;      
                        //        unacceptable_consecutive_window_loss_count++;
                        //        isAcceptableConsecutiveLoss = false;
                        //        break;
                        //    }
                        //}



                        //some time stamps from the mites are identical
                        // for interpolation that will cause an error
                        // simply take the first value for a time point and ignore the
                        // rest, another strategy would be to average over these values
                        // we decided, we will spread them out evenly as long as
                        // no excessive loss is experienced
                        // done down in the code
                        xvals[distinct_data_points] = (int)(current_time - window_start_time);
                        //signal value for the current sample and current axis.
                        yvals[distinct_data_points] = data[axes_index][sample_index];


                        //Point to the previous sample in the current window
                        if (sample_index == 0)
                            sample_index = Extractor.EXPECTED_WINDOW_SIZES[j] - 1;
                        else
                            sample_index--;

                        //store the previous sample time
                        //                        previous_time = current_time;

                        //Get the time of the new sample
                        current_time = data[time_index][sample_index];

                        //Point to the next entry in the interpolation array
                        distinct_data_points++;

                        //                        total_data_points++;
                    }
                    #endregion window grabbing

                    //Check if the captured window has acceptable loss rate
                    #region window quality checks
                    //Do not proceed if there was excessive consecutive loss of data frames
                    if (isAcceptableConsecutiveLoss == false)
                        break;

                    // all data for a specific sensor axis for the current window are stored
                    // in xvals and yvals
                    // check if the data is admissible for feature calculation according to the following
                    // criteria:
                    // 1- total lost data frames are within the loss rate
                    // 2- the number of consecutive lost packets is within our maximum_consecutive_loss parameter
                    if (distinct_data_points < Extractor.EXPECTED_GOOD_SAMPLING_RATES[j]) //discard this whole window of data
                    {
                        Extractor.discardedLossRateWindows++;
                        isAcceptableLossRate = false;
                        unacceptable_window_count++;
                        break;
                    }

                    #endregion window quality checks

                    //smoothen the axis values and store them in interpolated data array
                    #region window interpolation

                    //create 2 arrays with the exact size of the data points for interpolation
                    double[] admissible_xvals = new double[distinct_data_points];
                    double[] admissible_yvals = new double[distinct_data_points];
                    double expectedSpacing = Extractor.dconfiguration.WindowTime / (double)distinct_data_points;
                    double startTime = 0.0;
                    for (int k = 0; (k < distinct_data_points); k++)
                    {
                        admissible_xvals[k] = startTime+k*expectedSpacing;//xvals[distinct_data_points - k - 1];
                        admissible_yvals[k] = yvals[distinct_data_points - k - 1];
                    }
                    //if (spacingtws == null)
                   // {
                   //     spacingtws = new TextWriter[Extractor.sannotation.Sensors.Count];
                   //     for (int i = 0; (i < Extractor.sannotation.Sensors.Count); i++)
                    //    {
                    //        spacingtws[i] = new StreamWriter("\\test\\" + "SensorSpacing" + i + ".txt");
                    //    }
                   // }
                    
                    // smooth it using a cubic spline
                    CubicSpline cs= new CubicSpline(admissible_xvals, admissible_yvals);

                    //startval = xvals[distinct_data_points - 1].ToString("00.00");
                    // shrink or expand the data window using interpolation                
                    for (int k = 0; (k < INTERPOLATED_SAMPLING_RATE_PER_WINDOW); k++)
                    {
                        interpolated_data[interpolated_axes_index][k] = cs.interpolate(k * INTERPOLATED_SAMPLES_SPACING);
                        //check that the intrepolated values make sense.
                        //if ((interpolated_data[interpolated_axes_index][k] <= 0) || (interpolated_data[interpolated_axes_index][k] > 1024))
                        if ((interpolated_data[interpolated_axes_index][k] <= -6000) || (interpolated_data[interpolated_axes_index][k] > 6000))
                        {
                          //  errorFlag = 1;
                            return false;
                        }
                    }


                    #endregion window interpolation
                }
                #endregion sensor window grabbing and interpolation

                //spacingtws[j].WriteLine(startval);
                
            }
            #endregion sensors window grabbing and interpolation

            //If the data is of acceptable quality, calculate the features
            #region Calculate Feature Vector

            if ((isAcceptableLossRate == true) && (isAcceptableConsecutiveLoss == true))
            {           
                //Extract the features from the interpolated data
                //Extractor.Extract(interpolated_data);
                Extractor.Extract(interpolated_data);
                
                
                //Output the data to the ARFF file
                // tw.WriteLine(Extractor.toString() + "," + current_activity);
                //num_feature_windows++;
                // make sure the values of the features make sense... for example distance can 
                // only be -1024---- or so
                return true;
            }
            else  //the window is of poor quality, reinitialize and continue
            {
                isAcceptableConsecutiveLoss = true;
                isAcceptableLossRate = true;
                //errorFlag = 2;
                return false;
            }

            #endregion Calculate Feature Vector

           
        
        }