using System; using System.Collections.Generic; using System.Linq; namespace IOB_UT_NEXT.Objects { /// /// Classe gestione valori campionati su periodo /// public class sampleVect { #region Public Constructors /// /// Inizializzo l'oggetto /// public sampleVect() { // init valori default... windSize = baseUtils.CRI("countWindSize") > 0 ? baseUtils.CRI("countWindSize") : 60; lTime = new List(); lVal = new List(); } #endregion Public Constructors #region Public Properties /// /// Calcola il valore mediano... /// public double vcMedian { get { double answ = 0; // restituisce la mediana SE valida, altrimenti null... if (numElem > 2 && flWindSize > windSize) { try { // calcolo mediana! //answ = Statistics.Median(lVal.ToArray()); // rif: https://blogs.msmvps.com/deborahk/linq-mean-median-and-mode/ var sortedNumbers = lVal.OrderBy(n => n); int numCount = lVal.Count; int indice50 = lVal.Count / 2; if ((numCount % 2) == 0) { answ = ((sortedNumbers.ElementAt(indice50) + sortedNumbers.ElementAt(indice50 - 1)) / 2); } else { answ = sortedNumbers.ElementAt(indice50); } } catch { } } return answ; } } /// /// Verifica se la vc sia valida (ovvero almeno 2 valori e intervallo > window richiesta) /// public bool vcValid { get { return (flWindSize > windSize && numElem > 1); } } #endregion Public Properties #region Public Methods /// /// Aggiunge un valore alla serie ed eventualmente elimina i valori superflui a garantirne /// una finestra temporale valida /// /// /// public void addValue(DateTime tempo, int valore) { lTime.Add(tempo); lVal.Add(valore); // verifico se siano da accorciare le serie... ovvero i 2 intervalli ENTRAMBI sono // superiori al periodo minimo (in tal caso riduco.. while (flWindSize > windSize && slWindSize > windSize) { // elimino i 2 valori + vecchi lTime.RemoveAt(0); lVal.RemoveAt(0); // ora ricontrollo... } } #endregion Public Methods #region Protected Fields /// /// vettore valori temporali della serie /// protected List lTime; /// /// vettore valori puntuali della serie /// protected List lVal; /// /// Dimensione finestra di campionamento (secondi) /// protected int windSize; #endregion Protected Fields #region Protected Properties /// /// Verifica ampiezza finestra valori First-Last /// protected double flWindSize { get { double answ = 0; if (numElem > 1) { answ = lTime.Last().Subtract(lTime[0]).TotalSeconds; } return answ; } } /// /// Conteggio elementi /// protected int numElem { get { int answ = 0; try { answ = lTime.Count; } catch { } return answ; } } /// /// Verifica ampiezza finestra valori Second-Last /// protected double slWindSize { get { double answ = 0; if (numElem > 2) // altrimenti SE non ne ho almeno 3 NON posso avere secondo/ultimo... { answ = lTime.Last().Subtract(lTime[1]).TotalSeconds; } return answ; } } #endregion Protected Properties } }