/// <summary>
        /// Threshold phase
        /// </summary>
        /// <param name="definition">Aggregation Definition</param>
        /// <param name="observations">Observations</param>
        private void Thresholding(AggrConfig definition, IEnumerable<IObservation> observations)
        {
            var mean = observations.Select(e => e.Value).DefaultIfEmpty(0).Average();
            var q2 = observations.Select(e => e.Value * e.Value).DefaultIfEmpty(0).Average();
            int n = observations.Count();
            var std = q2 / n - mean * mean;

           
            //-----------------
            //THRESHOLDING
            //-----------------
            //If not thresholding required return mean
            if (definition.Threshold)
            {

                //Set threshold based on threshold type and value
                var threshold = definition.ThresholdValue;

                if (definition.ThresholdType == "std")
                {
                    threshold = mean + definition.ThresholdValue * std;
                }

                //New observation timestamp
                foreach (var obs in observations)
                {


                    obs.Value = (obs.Value > threshold) ? 1.0 : 0.0;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Load Aggregation Definition from file
        /// </summary>
        /// <param name="file">Input file</param>
        /// <returns>Aggregation Configuration Model <see cref="AggrConfig"/> </returns>
        public static AggrConfig LoadFromFile(string file)
        {
            AggrConfig     ret    = null;
            StreamReader   fstr   = null;
            JsonTextReader reader = null;

            try
            {
                fstr   = new StreamReader(file);
                reader = new JsonTextReader(fstr);
                JsonSerializer serializer = new JsonSerializer();
                ret = serializer.Deserialize <AggrConfig>(reader);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
                if (fstr != null)
                {
                    fstr.Dispose();
                }
            }

            return(ret);
        }
        /// <summary>
        /// Day Aggregation
        /// </summary>
        /// <param name="definition">Aggregation Definition</param>
        /// <param name="patientId">Patient Id</param>
        /// <param name="observations">Observations</param>
        /// <returns></returns>
        private IEnumerable<IObservation> PerformDayAggregation(AggrConfig definition, string patientId, IEnumerable<PDObservation> observations)
        {

            // Get Min and Max Date
            var minT = observations.Select(e => e.Timestamp).DefaultIfEmpty().Min();
            var maxT = observations.Select(e => e.Timestamp).DefaultIfEmpty().Max();

            List<IObservation> metaObservations = new List<IObservation>();
            var startDate = DateTimeExtensions.FromUnixTimestampMilli(minT);
            var endDate = DateTimeExtensions.FromUnixTimestampMilli(maxT);

            var startT = new DateTime(startDate.Year, startDate.Month, startDate.Day, 0, 0, 0, DateTimeKind.Utc).ToUnixTimestampMilli();
            var endT = new DateTime(endDate.Year, endDate.Month, endDate.Day, 23, 59, 59, DateTimeKind.Utc).ToUnixTimestampMilli();

            //Estimate mean and descriptive statistics
            for (long i = startT; i < endT; i += dayInterval)
            {
                double v = definition.Beta;
                foreach (var c in definition.Variables)
                {

                    var v1 = c.Weight * observations.Where(e => e.CodeId == c.Code&& e.Timestamp >= i && e.Timestamp < i + dayInterval).Select(e => e.Value).DefaultIfEmpty().Average();
                    v += v1;
                  
                }
                metaObservations.Add(new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = i, Value = v });
                
            }
            return metaObservations;
          
        }
示例#4
0
        /// <summary>
        /// Save Aggregation Definition to file
        /// </summary>
        /// <param name="definition">Aggregation Definition Model <see cref="AggrConfig"/></param>
        /// <param name="file">File to save the definition</param>
        public static void SaveToFile(AggrConfig definition, string file)
        {
            StreamWriter   fstr   = null;
            JsonTextWriter writer = null;

            try
            {
                fstr   = new StreamWriter(file);
                writer = new JsonTextWriter(fstr);
                JsonSerializer serializer = new JsonSerializer();
                serializer.Serialize(writer, definition);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
                if (fstr != null)
                {
                    fstr.Dispose();
                }
            }
        }
        /// <summary>
        /// Time Aggregation
        /// </summary>
        /// <param name="definition">Aggregation Definition</param>
        /// <param name="patientId">Patient Id</param>
        /// <param name="observations">Observations</param>
        /// <returns>List of observations</returns>
        private IEnumerable<IObservation> PerformTimeAggregation(AggrConfig definition,  string patientId, IEnumerable<PDObservation> observations)
        {

            List<IObservation> metaObservations = new List<IObservation>();        
            var minT = observations.Select(e => e.Timestamp).DefaultIfEmpty().Min();
            var maxT = observations.Select(e => e.Timestamp).DefaultIfEmpty().Max();

         
            var startDate = DateTimeExtensions.FromUnixTimestampMilli(minT);
            var endDate = DateTimeExtensions.FromUnixTimestampMilli(maxT);

            var t0= new DateTime(startDate.Year, startDate.Month, startDate.Day, 0, 0, 0, DateTimeKind.Utc).ToUnixTimestampMilli();
            var tmax = new DateTime(endDate.Year, endDate.Month, endDate.Day, 23, 59, 59, DateTimeKind.Utc).ToUnixTimestampMilli();

            for (long j = 0; j <= dayInterval; j += timeInterval)
            {
                               
                double m = 0;              
                int n0 = 0;
                double v = definition.Beta;
                foreach (var c in definition.Variables)
                {
                    n0 = 0;
                    m = 0;
                    for (long i = t0; i <= tmax; i += dayInterval)
                    {
                        long te = i + j + timeInterval;
                        long ts = i + j;
                        m += observations.Where(e => e.Timestamp >= ts && e.Timestamp < te&&e.CodeId==c.Code).Select(e => e.Value).DefaultIfEmpty(0).Sum();
                        n0 += observations.Where(e => e.Timestamp >= ts && e.Timestamp < te && e.CodeId == c.Code).Count();
                    }
                    if (n0 > 0)
                    {
                        
                        v +=( m/n0) * c.Weight;
                    }
                  
                }

                if (n0 > 0)
                {                 
                
                    metaObservations.Add(new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = j, Value = v, Weight = n0 });
                }

            }

            return metaObservations;
          
        }
        /// <summary>
        /// PerformAggregation Aggregation
        /// </summary>
        /// <param name="definition">Aggregation Definition</param>
        /// <param name="patientId">Patient Id</param>
        /// <param name="timestamp">Timestamp</param>
        /// <param name="observations">Observations</param>
        /// <returns>List of observations</returns>
        private IEnumerable<IObservation> PerformAggregation(AggrConfig definition, string patientId, long timestamp, IEnumerable<PDObservation> observations)
        {

            //-----------------
            // 1st Level Aggregation
            //------------
            IEnumerable<IObservation> metaObservations = null;
            //return PerformTotalAggregation(definition, patientId, timestamp, observations);

            if (definition.AggregationType == TimeAggregationType)
            {

                metaObservations= PerformTimeAggregation(definition, patientId, observations);


            }
            else if (definition.AggregationType == DayAggregationType)
            {

                metaObservations= PerformDayAggregation(definition, patientId, observations);

            }
            else
            {
                metaObservations= PerformTotalAggregation(definition, patientId, timestamp, observations);

            }


            if(metaObservations==null)
            {
                //Something wrong happened!!
                throw new Exception();

            }

            //---------------------
            //Threshold meta-observations
            //---------------------            
            Thresholding(definition, metaObservations);


            //---------------------
            //2nd Level aggregation
            //---------------------      
            return MetaAggregation(definition, patientId, metaObservations);



        }
        /// <summary>
        /// Total Aggregation
        /// </summary>
        /// <param name="definition">Aggregation definition</param>
        /// <param name="patientId">Patient Id</param>
        /// <param name="timestamp">Timestamp</param>
        /// <param name="observations">Input Observations</param>
        /// <returns>List of output observations</returns>
        private IEnumerable<IObservation> PerformTotalAggregation(AggrConfig definition,string patientId,long timestamp,IEnumerable<PDObservation> observations)
        {
                   
            double v = definition.Beta;
            foreach (var c in definition.Variables)
            {

                var v1 = c.Weight * observations.Where(e=>e.CodeId==c.Code).Select(e => e.Value).DefaultIfEmpty().Average();
                v += v1;

            }
            return new List<IObservation>() { new PDObservation() { Value = v, PatientId = patientId, CodeId = definition.Code, Timestamp = timestamp } };

            

        }
        private AggrConfig LoadAggrDefinition(string name)
        {
            return AggrConfig.LoadFromFile(name);

        }
        /// <summary>
        /// 2nd Level Aggregation
        /// </summary>
        /// <param name="definition">Aggregation Definition</param>
        /// <param name="patientId">Patient Id</param>
        /// <param name="metaObservations">Observations</param>
        /// <returns>List of observations</returns>
        private IEnumerable<IObservation> MetaAggregation(AggrConfig definition, string patientId, IEnumerable<IObservation> metaObservations)
        {
           

            var endT = metaObservations.Select(e => e.Timestamp).DefaultIfEmpty().Max();
            
            if (definition.MetaAggregationType == "sum")
            {

                return new List<IObservation>() { new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = endT, Value = definition.MetaScale * metaObservations.Select(e => e.Value).DefaultIfEmpty(0).Sum() } };
            }
            else if (definition.MetaAggregationType == "average")
            {
                return new List<IObservation>() { new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = endT, Value = definition.MetaScale * metaObservations.Select(e => e.Value).DefaultIfEmpty(0).Average() } };

            }
       
            else if (definition.MetaAggregationType == "mfi")
            {
                return new List<IObservation>() { new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = endT, Value = definition.MetaScale * (metaObservations.Select(e => e.Value).DefaultIfEmpty(0).Max()- metaObservations.Select(e => e.Value).DefaultIfEmpty(0).Average()) } };

            }
            else if (definition.MetaAggregationType == "count")
            {
                return new List<IObservation>() { new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = endT, Value = definition.MetaScale * metaObservations.Count() } };

            }
            else if (definition.MetaAggregationType == "max")
            {
                return new List<IObservation>() { new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = endT, Value = definition.MetaScale * metaObservations.Select(e => e.Value).DefaultIfEmpty(0).Max() } };

            }
            else if (definition.MetaAggregationType == "min")
            {
                return new List<IObservation>() { new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = endT, Value = definition.MetaScale * metaObservations.Select(e => e.Value).DefaultIfEmpty(0).Min() } };

            }
            else if (definition.MetaAggregationType == "std")
            {

                var fmean = metaObservations.Select(e => e.Value).DefaultIfEmpty(0).Average();
                var fq2 = metaObservations.Select(e => e.Value * e.Value).DefaultIfEmpty(0).Average();
                int fn = metaObservations.Count();
                var fstd = fq2 / fn - fmean * fmean;

                return new List<IObservation>() { new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = endT, Value = definition.MetaScale * fstd } };

            }
            else if (definition.MetaAggregationType == "cv")
            {

                var fmean = metaObservations.Select(e => e.Value).DefaultIfEmpty(0).Average();
                var fq2 = metaObservations.Select(e => e.Value * e.Value).DefaultIfEmpty(0).Average();
                int fn = metaObservations.Count();
                var fstd = fq2 / fn - fmean * fmean;

                return new List<IObservation>() { new PDObservation() { CodeId = definition.Code, PatientId = patientId, Timestamp = endT, Value =definition.MetaScale*100*fstd/fmean } };

            }
            else
            {

                return metaObservations;

            }


        }
        /// <summary>
        /// Run Aggregation
        /// This method 
        /// 1) loads the aggregation definition
        /// 2) Fetch all required observations using the DataProxy
        /// 3) Calls the PerformAggregation method to perform the aggregation and returns a new observation
        /// 
        /// </summary>
        /// <param name="patientId">Patient Id</param>
        /// <param name="code">Meta observation Code</param>
        /// <param name="lastExecutionTime">Last execution time</param>
        /// <param name="aggregationType">Overrides the default aggregation type</param>
        /// <param name="filterType">Overrides the default filter type</param>
        /// <returns>List of observations</returns>

        public async Task<IEnumerable<IObservation>> Run(string patientId, string code, DateTime? lastExecutionTime,string aggregationType=null,string filterType=null)
        {
            if (patientId == null)
            {
                throw new ArgumentNullException(nameof(patientId));
            }

            if (code == null)
            {
                throw new ArgumentNullException(nameof(code));
            }

            // Get Definition File Name from AggrDefinitionDictionary

            if (_definition == null)
                _definition = AggrConfig.FromString(_aggrDefinitionDictionary.GetJsonConfigFromCode(code));

            if (_definition == null)
            {
                throw new AggrDefinitionNotFoundException(nameof(_definition));
            }


            if(!string.IsNullOrEmpty(aggregationType))
            {
                _definition.AggregationType = aggregationType;
            }


            if (!string.IsNullOrEmpty(filterType))
            {
                _definition.MetaAggregationType = filterType;
            }

            var lastExecutionTimeStamp = lastExecutionTime.HasValue ? lastExecutionTime.Value.ToUnixTimestamp() * 1000 : 0;

            //Get Data
            List<PDObservation> observations = new List<PDObservation>();
            foreach (var c in _definition.Variables)
            {              
                    try
                    {
                        //Get Observations For patient
                        var ret = await _proxy.Get<PDObservation>( MAXTAKE, 0, GetFilter(patientId, c.Code, lastExecutionTimeStamp, _definition.AggregationType), null);
                        observations.AddRange(ret);

                    }
                    catch (Exception ex)
                    {
                        _logger?.LogError(ex, "Error in aggregation");
                    }
                
            }


            var metaObservation = PerformAggregation(_definition, patientId, lastExecutionTimeStamp, observations);
            return metaObservation;



        }
示例#11
0
        /// <summary>
        /// Create Aggregation Definition from string
        /// </summary>
        /// <param name="configJson">Config in json</param>
        /// <returns>Aggregation Configuration Model <see cref="AggrConfig"/></returns>
        public static AggrConfig FromString(string configJson)
        {
            AggrConfig ret = null;

            return(ret = JsonConvert.DeserializeObject <AggrConfig>(configJson));
        }