Esempio n. 1
0
        /// <summary>
        /// This method writes a new record to the database table for a regular time series.
        /// The method will record extra parameters (other than those that are saved
        /// as class-level properties of this object) into the database record using the strings
        /// in the method parameters extraParamNames and extraParamValues.  This method does not
        /// make any changes to the trace table.
        /// </summary>
        /// <param name="doWriteToDB">true if the method should actually save the timeseries to the database</param>
        /// <param name="tsImport">TSImport object into which the method will record values that it has computed.
        /// If this parameter is null, then the method will skip the recording of such paramters to an object.</param>
        /// <param name="timeStepUnit">TSDateCalculator.TimeStepUnitCode value for Minute,Hour,Day,Week,Month, or Year</param>
        /// <param name="timeStepQuantity">The number of the given unit that defines the time step.
        /// For instance, if the time step is 6 hours long, then this value is 6.</param>
        /// <param name="timeStepCount">The number of time steps in the time series</param>
        /// <param name="outStartDate">date of the first time step in the series</param>
        /// <param name="extraParamNames">A list of field names that the the method should fill, in addition
        /// to the fields that the TimeSeriesLibrary is designed to maintain.  Every item in this list must
        /// be matched to an item in extraParamValues.</param>
        /// <param name="extraParamValues">A list of field values that the the method should fill, in addition
        /// to the fields that the TimeSeriesLibrary is designed to maintain.  Every item in this list must
        /// be matched to an item in extraParamNames.</param>
        /// <returns>the primary key Id value of the new record that was created</returns>
        public unsafe int WriteParametersRegular(
            bool doWriteToDB, TSImport tsImport,
            short timeStepUnit, short timeStepQuantity,
            int timeStepCount, DateTime outStartDate,
            String extraParamNames, String extraParamValues)
        {
            ErrorCheckWriteValues(doWriteToDB, tsImport);
            // The method's parameters are used to compute the meta-parameters of this time series
            TSParameters.SetParametersRegular(
                (TSDateCalculator.TimeStepUnitCode)timeStepUnit, timeStepQuantity,
                timeStepCount, outStartDate,
                // new time series are always compressed by the current compression technique
                TSBlobCoder.currentCompressionCode);
            IsInitialized = true;
            // Compute the Checksum for this time series ensemble.  Because this is a newly
            // written series, there are not yet any traces to incorporate into the checksum
            // (presumably those will be added later).
            Checksum = TSBlobCoder.ComputeChecksum(TSParameters, new List <ITimeSeriesTrace>());
            // WriteParameters method will handle all of the database interaction
            if (doWriteToDB)
            {
                WriteParameters(extraParamNames, extraParamValues);
            }

            return(Id);
        }
Esempio n. 2
0
        /// <summary>
        /// Method reads the irregular time series matching the given ID and trace number, storing the dates and
        /// values into the given array of TSDateValueStruct (a struct containing the date/value pair).
        /// The method starts populating the array at the given start date, filling in no more than
        /// the number of values, that are requested, and not reading past the given end date
        /// </summary>
        /// <param name="id">ID id of the time series</param>
        /// <param name="traceNumber">number of the trace to read</param>
        /// <param name="nReqValues">number of values requested to read</param>
        /// <param name="dateValueArray">array requrested to fill with date/value pairs</param>
        /// <param name="reqStartDate">start date requested</param>
        /// <param name="reqEndDate">end date requested</param>
        /// <returns>The number of values actually filled into the array</returns>
        public unsafe int ReadValuesIrregular(int id, int traceNumber,
                                              int nReqValues, TSDateValueStruct[] dateValueArray, DateTime reqStartDate, DateTime reqEndDate)
        {
            // Initialize class fields other than the BLOB of data values
            if (!IsInitialized)
            {
                Initialize(id);
            }

            // This method can only process irregular-time-step series
            if (TimeStepUnit != TSDateCalculator.TimeStepUnitCode.Irregular)
            {
                throw new TSLibraryException(ErrCode.Enum.Record_Not_Irregular,
                                             String.Format("The method can only process irregular time series, but" +
                                                           "the record with Id {0} is regular.", id));
            }
            // If the end date requested by the caller is such that the stored time series
            // does not overlap, then we don't need to go any further.
            if (reqEndDate < BlobStartDate)
            {
                return(0);
            }

            // byte array (the BLOB) that will be read from the database.
            Byte[] blobData = null;
            // method ReadValues reads data from the database into the byte array
            int timeStepCount = ReadValues(id, traceNumber, ref blobData);

            // convert the byte array into date/value pairs
            return(TSBlobCoder.ConvertBlobToArrayIrregular(timeStepCount, true, nReqValues,
                                                           reqStartDate, reqEndDate,
                                                           blobData, dateValueArray, CompressionCode));
        }
Esempio n. 3
0
 /// <summary>
 /// This method computes a Checksum for the timeseries.  The input to the hash includes
 /// the list of parameters of the time series, and the list of checksums for each of the traces
 /// in the time series ensemble.  The list of the traces' checksums are passed to this method
 /// within a list of ITimeSeriesTrace objects.  This method does not modify the object given
 /// in the traceList parameter or assign any property values to any of its items.
 /// </summary>
 /// <param name="timeStepUnit">TSDateCalculator.TimeStepUnitCode value for Minute, Hour, Day,
 /// Week, Month, Year, or Irregular</param>
 /// <param name="timeStepQuantity">The number of the given unit that defines the time step.
 /// For instance, if the time step is 6 hours long, then this value is 6.</param>
 /// <param name="blobStartDate">Date of the first time step in the BLOB</param>
 /// <param name="traceList">a list of trace object whose checksums have already been computed.</param>
 /// <returns>the Checksum as a byte[16] array</returns>
 public byte[] ComputeChecksum(
     TSDateCalculator.TimeStepUnitCode timeStepUnit, short timeStepQuantity,
     DateTime blobStartDate, List <ITimeSeriesTrace> traceList)
 {
     return(TSBlobCoder.ComputeChecksum(timeStepUnit, timeStepQuantity,
                                        blobStartDate, traceList));
 }
Esempio n. 4
0
        /// <summary>
        /// This method converts a List of TimeSeriesValue objects into a BLOB (byte array) of
        /// time series values and computes a checksum from the BLOB.  This method assigns the new values
        /// of the ValueBlob, Checksum, EndDate, and TimeStepCount to the object given in the traceObject
        /// parameter. The TraceNumber property of the traceObject parameter must be set before calling
        /// this method.
        ///
        /// The entire List is converted into the BLOB--i.e., the method does not take any
        /// parameters for limiting the size of the List that is created.  This method will
        /// throw exceptions if the meta-parameters that are passed in are not consistent
        /// with the List of TimeSeriesValue objects.
        /// </summary>
        /// <param name="timeStepUnit">TSDateCalculator.TimeStepUnitCode value for
        /// Minute, Hour, Day, Week, Month, Year, or Irregular</param>
        /// <param name="timeStepQuantity">The number of the given unit that defines the time step.
        /// For instance, if the time step is 6 hours long, then this value is 6.</param>
        /// <param name="timeStepCount">The number of time steps stored in the BLOB</param>
        /// <param name="blobStartDate">Date of the first time step in the BLOB</param>
        /// <param name="blobEndDate">Date of the last time step in the BLOB</param>
        /// <param name="dateValueList">A List of TimeSeriesValue objects that will be converted to a BLOB</param>
        /// <param name="traceObject">an object which contains the a TraceNumber property that is used to
        /// compute the checksum.  The computed BLOB and checksum are both saved to the appropriate properties
        /// of this object.</param>
        /// <param name="compressionCode">a generation number that indicates what compression technique to use</param>
        /// <returns>The BLOB (byte array) of time series values that was created from dateValueList</returns>
        public byte[] ConvertListToBlobWithChecksum(
            TSDateCalculator.TimeStepUnitCode timeStepUnit, short timeStepQuantity,
            int timeStepCount, DateTime blobStartDate, DateTime blobEndDate,
            List <TimeSeriesValue> dateValueList,
            ITimeSeriesTrace traceObject, out int compressionCode)
        {
            // Error checks
            if (dateValueList.Count != timeStepCount)
            {
                throw new TSLibraryException(ErrCode.Enum.Checksum_Improper_Count);
            }
            if (dateValueList[0].Date != blobStartDate)
            {
                throw new TSLibraryException(ErrCode.Enum.Checksum_Improper_StartDate);
            }
            if (dateValueList.Last().Date != blobEndDate)
            {
                throw new TSLibraryException(ErrCode.Enum.Checksum_Improper_EndDate);
            }

            // When compressing, we always use the latest compression method
            compressionCode = TSBlobCoder.currentCompressionCode;
            // Assign properties to the Trace object
            if (traceObject.EndDate != blobEndDate)
            {
                traceObject.EndDate = blobEndDate;
            }
            if (traceObject.TimeStepCount != timeStepCount)
            {
                traceObject.TimeStepCount = timeStepCount;
            }

            // Convert the List dateValueList into a BLOB.
            if (timeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
            {
                // IRREGULAR TIME SERIES

                // The method in TSBlobCoder can only process an array of TSDateValueStruct.  Therefore
                // we convert the List of objects to an Array of struct instances.
                TSDateValueStruct[] dateValueArray = dateValueList.Select(tsv => (TSDateValueStruct)tsv).ToArray();
                // Let the method in TSBlobCoder class do all the work
                TSBlobCoder.ConvertArrayToBlobIrregular(dateValueArray, compressionCode, traceObject);
            }
            else
            {
                // REGULAR TIME SERIES

                // The method in TSBlobCoder can only process an array of double values.  Therefore
                // we convert the List of date/value objects to an Array values.
                double[] valueArray = dateValueList.Select(dv => dv.Value).ToArray();
                // Let the method in TSBlobCoder class do all the work
                TSBlobCoder.ConvertArrayToBlobRegular(valueArray, compressionCode, traceObject);
            }

            return(traceObject.ValueBlob);
        }
Esempio n. 5
0
        /// <summary>
        /// This method prepares a new record for the trace table for a regular time step series.
        /// The method converts the given valueArray into the BLOB that is actually stored in
        /// the table.  The method computes the checksum of the trace, and computes a new checksum
        /// for the parameters table to reflect the fact that a new trace has been added to the ensemble.
        /// For both the insertion to the trace table and the update to the parameters table, this method
        /// only stores changes in DataTable objects--nothing is changed in the database. In order for
        /// the changes to be sent to the database, the method TSConnection.CommitNewTraceWrites must
        /// be called after WriteTraceRegular has been called for all new traces.
        /// </summary>
        /// <param name="id">identifying primary key value of the the parameters table for the record
        /// that this trace belongs to</param>
        /// <param name="doWriteToDB">true if the method should actually save the timeseries to the database</param>
        /// <param name="tsImport">TSImport object into which the method will record values that it has computed.
        /// If this parameter is null, then the method will skip the recording of such paramters to an object.</param>
        /// <param name="traceNumber">number of the trace to write</param>
        /// <param name="valueArray">The array of values to be written to the database</param>
        public unsafe void WriteTraceRegular(int id,
                                             bool doWriteToDB, TSImport tsImport,
                                             int traceNumber,
                                             double[] valueArray)
        {
            // Initialize class fields other than the BLOB of data values
            if (!IsInitialized)
            {
                Initialize(id, true);
            }

            // This method can only process regular-time-step series
            if (TimeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
            {
                throw new TSLibraryException(ErrCode.Enum.Record_Not_Regular,
                                             String.Format("The method can only process regular time series, but" +
                                                           "the record with Id {0} is irregular.", id));
            }
            // Create a trace object
            int timeStepCount            = valueArray.Count();
            ITimeSeriesTrace traceObject = new TSTrace
            {
                TraceNumber   = traceNumber,
                TimeStepCount = timeStepCount,
                EndDate       = TSDateCalculator.IncrementDate(BlobStartDate,
                                                               TimeStepUnit, TimeStepQuantity, timeStepCount - 1)
            };

            if (tsImport != null)
            {
                tsImport.TraceList.Add(traceObject);
            }
            else
            {
                TraceList.Add(traceObject);
            }
            // Convert the array of double values into a byte array...a BLOB
            TSBlobCoder.ConvertArrayToBlobRegular(valueArray, CompressionCode, traceObject);

            // Create a new record for the trace table
            // (but for now it is only stored in a DataTable object)
            if (doWriteToDB)
            {
                WriteTrace(traceObject);
            }
            // Compute a new checksum for the parameters table
            // (but for now it is only stored in a DataTable object)
            UpdateParametersChecksum(doWriteToDB, tsImport);
        }
Esempio n. 6
0
        /// <summary>
        /// This computes a new value for the Checksum field of the parameters table.  It does not save
        /// this change to the database, but to a DataTable object.  It is assumed that method
        /// TSConnection.CommitNewTraceWrites will be called later in order to send the changes to the
        /// database. If parameter 'toWriteToDB' is false, then this method can simply save the
        /// new Checksum value to the object given in the 'tsImport' parameter.
        /// </summary>
        /// <param name="toWriteToDB">true if the method should actually
        /// save the timeseries to the database</param>
        /// <param name="tsImport">TSImport object into which the method will record values
        /// that it has computed. If this parameter is null, then the method will skip the recording
        /// of such paramters to an object.</param>
        private void UpdateParametersChecksum(Boolean toWriteToDB, TSImport tsImport)
        {
            // The collection in variable 'traceObjects' contains one item for each trace for this
            // time series.  The primary purpose of the list is to store the checksum for each trace,
            // since the checksum of the timeseries is computed from the list of checksums from each
            // of its traces.
            List <ITimeSeriesTrace> traceObjects;

            if (tsImport != null)
            {
                traceObjects = tsImport.TraceList;
            }
            else
            {
                traceObjects = TraceList;
            }

            // Compute the new checksum of the ensemble
            Checksum = TSBlobCoder.ComputeChecksum(TimeStepUnit, TimeStepQuantity,
                                                   BlobStartDate, traceObjects);
            if (toWriteToDB)
            {
                DataTable dataTable;
                // Attempt to get the existing DataTable object from the collection that is kept by
                // the TSConnection object.  If this fails, then we'll create a new DataTable.
                if (TSConnection.BulkCopyDataTables.TryGetValue(ParametersTableName, out dataTable) == false)
                {
                    // Create the DataTable object and add columns that match the columns
                    // of the database table.
                    dataTable = new DataTable();
                    dataTable.Columns.Add("Id", typeof(int));
                    dataTable.Columns.Add("Checksum", typeof(byte[]));
                    // Add the DataTable to a collection that is kept in the TSConnection object.
                    TSConnection.BulkCopyDataTables.Add(ParametersTableName, dataTable);
                }
                dataTable.Rows.Add(Id, Checksum);
            }
        }
Esempio n. 7
0
 /// <summary>
 /// This method computes the checksum for an individual trace of a time series, where the time
 /// series is understood to be an ensemble of one or more traces.  The checksum of a trace is
 /// computed from the trace number and from the BLOB that contains the values for each time
 /// step of the time series.
 /// </summary>
 /// <param name="traceNumber">the number for identifying the trace</param>
 /// <param name="valueBlob">the BLOB that contains the values for each time step
 /// of the time series.</param>
 public byte[] ComputeTraceChecksum(int traceNumber, byte[] valueBlob)
 {
     return(TSBlobCoder.ComputeTraceChecksum(traceNumber, valueBlob));
 }
Esempio n. 8
0
        /// <summary>
        /// This private method creates a List of TimeSeriesValue objects from the given BLOB (byte array)
        /// of time series values.  The method takes parameters for a maximum number of values,
        /// an earliest date, and a latest date, so that only a portion of the BLOB might be
        /// converted to the List.  This method is designed to do the operations that are common between
        /// the public methods ConvertBlobToListLimited() and ConvertBlobToListAll().
        /// </summary>
        /// <param name="timeStepUnit">TSDateCalculator.TimeStepUnitCode value for Minute,Hour,Day,Week,Month, Year, or Irregular</param>
        /// <param name="timeStepQuantity">The number of the given unit that defines the time step.
        /// For instance, if the time step is 6 hours long, then this value is 6.  If timeStepUnit is
        /// Irregular, then this value is ignored.</param>
        /// <param name="timeStepCount">the number of time steps that are stored in the blob</param>
        /// <param name="blobStartDate">The DateTime value of the first time step in the BLOB. If
        /// timeStepUnit is Irregular, then this value is ignored.</param>
        /// <param name="applyLimits">If value is true, then nReqValues, reqStartDate, and reqEndDate will be
        /// used to limit the portion of the BLOB that is converted to dateValueList.  If the value is false, then
        /// nReqValues, reqStartDate, and reqEndDate will be ignored.</param>
        /// <param name="nReqValues">The maximum number of time steps that should be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="reqStartDate">The earliest date that will be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="reqEndDate">The latest date that will be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="blobData">The BLOB (byte array) that this method will convert into a List</param>
        /// <param name="dateValueList">The List of TimeSeriesValues that this method will create from the BLOB.</param>
        /// <param name="compressionCode">a generation number that indicates what compression technique to use</param>
        /// <returns>The number of time steps added to dateValueList</returns>
        private unsafe int ConvertBlobToList(
            TSDateCalculator.TimeStepUnitCode timeStepUnit, short timeStepQuantity,
            int timeStepCount, DateTime blobStartDate, Boolean applyLimits,
            int nReqValues, DateTime reqStartDate, DateTime reqEndDate,
            Byte[] blobData, ref List <TimeSeriesValue> dateValueList, int compressionCode)
        {
            int nValuesRead = 0;

            if (timeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
            {
                // IRREGULAR TIME SERIES

                // If we're not limiting the output list (i.e., we're returning every time step from
                // the BLOB), then set the size of the intermediate array to match the size of the BLOB.
                if (applyLimits == false)
                {
                    nReqValues = timeStepCount;
                }
                // Allocate an array of date/value pairs that TSBlobCoder method will fill
                TSDateValueStruct[] dateValueArray = new TSDateValueStruct[nReqValues];
                // Method in the TSBlobCoder class does the real work
                nValuesRead = TSBlobCoder.ConvertBlobToArrayIrregular(timeStepCount, applyLimits,
                                                                      nReqValues, reqStartDate, reqEndDate,
                                                                      blobData, dateValueArray, compressionCode);
                // resize the array so that the List that we make from it will have exactly the right size
                if (nValuesRead != nReqValues)
                {
                    Array.Resize <TSDateValueStruct>(ref dateValueArray, nValuesRead);
                }
                // Convert the array of date/value pairs into the List that will be used by the caller
                dateValueList = dateValueArray
                                .Select(tsv => (TimeSeriesValue)tsv).ToList <TimeSeriesValue>();
            }
            else
            {
                // REGULAR TIME SERIES

                // If we're not limiting the output list (i.e., we're returning every time step from
                // the BLOB), then set the size of the intermediate array to match the size of the BLOB.
                if (applyLimits == false)
                {
                    nReqValues = timeStepCount;
                }
                // Allocate an array of values that TSBlobCoder method will fill
                double[] valueArray = new double[nReqValues];
                // Method in the TSBlobCoder class does the real work
                nValuesRead = TSBlobCoder.ConvertBlobToArrayRegular(timeStepUnit, timeStepQuantity,
                                                                    timeStepCount, blobStartDate, applyLimits,
                                                                    nReqValues, reqStartDate, reqEndDate,
                                                                    blobData, valueArray, compressionCode);
                // Allocate an array to hold the time series' date values
                DateTime[] dateArray = new DateTime[nValuesRead];
                // Fill the array with the date values corresponding to the time steps defined
                // for this time series in the database.
                TSDateCalculator.FillDateArray(timeStepUnit, timeStepQuantity, nValuesRead, dateArray, reqStartDate);
                // Allocate a List of date/value pairs that will be used by the caller
                dateValueList = new List <TimeSeriesValue>(nValuesRead);
                // Loop through all values, building the List of date/value pairs out of the
                // primitive array of dates and primitive array of values.
                int i;
                for (i = 0; i < nValuesRead; i++)
                {
                    dateValueList.Add(new TimeSeriesValue {
                        Date = dateArray[i], Value = valueArray[i]
                    });
                }
                nValuesRead = i;
            }
            return(nValuesRead);
        }