Source code for dtale.gage_rnr

# coding=utf-8
from enum import Enum
import numpy as np
import math
import scipy.stats as stats


[docs]class Component(Enum): """Enum containing the different Variance parts of GageRnR.""" OPERATOR = 0 PART = 1 OPERATOR_BY_PART = 2 MEASUREMENT = 3 TOTAL = 4
ComponentNames = { Component.OPERATOR: "Operator", Component.PART: "Part", Component.OPERATOR_BY_PART: "Operator by Part", Component.MEASUREMENT: "Measurement", Component.TOTAL: "Total", "GageRnR": "Gage R&R", }
[docs]class Result(Enum): """Enum containing the measurements calculated by GageRnR.""" DF = 0 Mean = 1 SS = 3 MS = 4 Var = 5 Std = 6 F = 7 P = 8 W = 9 K = 10 Bias = 11
ResultNames = { Result.DF: "DF", Result.SS: "SS", Result.MS: "MS", Result.Var: "Var (σ²)", Result.Std: "Std (σ)", Result.F: "F-value", Result.P: "P-value", }
[docs]class Statistics(object): title = "Statistics" def __init__(self, data, labels=None): self.data = data self.parts = data.shape[1] self.operators = data.shape[0] self.measurements = data.shape[2] if labels is None: self.labels = {} else: self.labels = labels if "Operator" not in self.labels: self.labels["Operator"] = [ ("Operator %d" % x) for x in range(self.operators) ] if "Part" not in self.labels: self.labels["Part"] = [("Part %d" % x) for x in range(self.parts)]
[docs] def calculate_mean(self): """Calculate Mean.""" mu = np.array([np.mean(self.data)]) omu = np.mean(self.data, axis=1) omu = np.mean(omu, axis=1) pmu = np.mean(self.data, axis=0) pmu = np.mean(pmu, axis=1) emu = np.mean(self.data, axis=2) emu = emu.reshape(self.parts * self.operators) return { Component.TOTAL: mu, Component.OPERATOR: omu, Component.PART: pmu, Component.MEASUREMENT: emu, }
[docs] def calculate_std(self): std = np.array([np.std(self.data, ddof=1)]) stdo = np.std(self.data_to_operators(), axis=1, ddof=1) stdp = np.std(self.data_to_parts(), axis=1, ddof=1) return {Component.TOTAL: std, Component.OPERATOR: stdo, Component.PART: stdp}
[docs] def calculate(self): self.result = dict() self.result[Result.Mean] = self.calculate_mean() self.result[Result.Std] = self.calculate_std()
[docs] def data_to_parts(self): data = np.transpose(self.data, axes=(1, 0, 2)) return data.reshape(self.parts, self.measurements * self.operators)
[docs] def data_to_operators(self): return self.data.reshape(self.operators, self.measurements * self.parts)
[docs]class GageRnR(Statistics): """Main class for calculating GageRnR.""" GRR = "GageRnR" title = "Gage R&R" def __init__(self, data): """Initialize GageRnR algorithm. :param numpy.array data: The data tha we want to analyse using GageRnR. The input should be structured in a 3d array n[i,j,k] where i = operator, j = part, k = measurement """ super(GageRnR, self).__init__(data)
[docs] def calculate(self): """Calculate GageRnR.""" self.result = dict() self.result[Result.DF] = self.calculate_dof() self.result[Result.Mean] = self.calculate_mean() self.result[Result.SS] = self.calculate_ss() self.result[Result.MS] = self.calculate_ms( self.result[Result.DF], self.result[Result.SS] ) self.result[Result.Var] = self.calculate_var(self.result[Result.MS]) self.result[Result.Std] = self.calculate_std(self.result[Result.Var]) self.result[Result.F] = self.calculate_f(self.result[Result.MS]) self.result[Result.P] = self.calculate_p( self.result[Result.DF], self.result[Result.F] ) return self.result
[docs] def calculate_dof(self): """Calculate Degrees of freedom.""" oDoF = self.operators - 1 pDoF = self.parts - 1 opDoF = (self.parts - 1) * (self.operators - 1) eDof = self.parts * self.operators * (self.measurements - 1) totDof = self.parts * self.operators * self.measurements - 1 return { Component.OPERATOR: oDoF, Component.PART: pDoF, Component.OPERATOR_BY_PART: opDoF, Component.MEASUREMENT: eDof, Component.TOTAL: totDof, }
[docs] def calculate_squares(self): """Calculate Squares.""" mean = self.calculate_mean() tS = (self.data - mean[Component.TOTAL]) ** 2 oS = (mean[Component.OPERATOR] - mean[Component.TOTAL]) ** 2 pS = (mean[Component.PART] - mean[Component.TOTAL]) ** 2 dataE = self.data.reshape(self.operators * self.parts, self.measurements) meanMeas = np.repeat(mean[Component.MEASUREMENT], self.measurements) meanMeas = meanMeas.reshape(self.operators * self.parts, self.measurements) mS = (dataE - meanMeas) ** 2 return { Component.TOTAL: tS, Component.OPERATOR: oS, Component.PART: pS, Component.MEASUREMENT: mS, }
[docs] def calculate_sum_of_deviations(self): """Calculate Sum of Deviations.""" squares = self.calculate_squares() SD = dict() for key in squares: SD[key] = np.sum(squares[key]) return SD
[docs] def calculate_ss(self): """Calculate Sum of Squares.""" SS = self.calculate_sum_of_deviations() SS[Component.OPERATOR] = self.parts * self.measurements * SS[Component.OPERATOR] SS[Component.PART] = self.operators * self.measurements * SS[Component.PART] SS[Component.OPERATOR_BY_PART] = SS[Component.TOTAL] - ( SS[Component.OPERATOR] + SS[Component.PART] + SS[Component.MEASUREMENT] ) return SS
[docs] def calculate_ms(self, dof, SS): """Calculate Mean of Squares.""" MS = dict() for key in SS: MS[key] = SS[key] / dof[key] return MS
[docs] def calculate_var(self, MS): """Calculate GageRnR Variances.""" Var = dict() Var[Component.MEASUREMENT] = MS[Component.MEASUREMENT] Var[Component.OPERATOR_BY_PART] = ( MS[Component.OPERATOR_BY_PART] - MS[Component.MEASUREMENT] ) / self.parts Var[Component.OPERATOR] = ( MS[Component.OPERATOR] - MS[Component.OPERATOR_BY_PART] ) / (self.parts * self.measurements) Var[Component.PART] = (MS[Component.PART] - MS[Component.OPERATOR_BY_PART]) / ( self.operators * self.measurements ) for key in Var: if Var[key] < 0: Var[key] = 0 Var[Component.TOTAL] = ( Var[Component.OPERATOR] + Var[Component.PART] + Var[Component.OPERATOR_BY_PART] + Var[Component.MEASUREMENT] ) Var[GageRnR.GRR] = ( Var[Component.MEASUREMENT] + Var[Component.OPERATOR] + Var[Component.OPERATOR_BY_PART] ) return Var
[docs] def calculate_std(self, Var): """Calculate GageRnR Standard Deviations.""" Std = dict() for key in Var: Std[key] = math.sqrt(Var[key]) return Std
[docs] def calculate_f(self, MS): """Calculate F-Values.""" F = dict() F[Component.OPERATOR] = MS[Component.OPERATOR] / MS[Component.OPERATOR_BY_PART] F[Component.PART] = MS[Component.PART] / MS[Component.OPERATOR_BY_PART] F[Component.OPERATOR_BY_PART] = ( MS[Component.OPERATOR_BY_PART] / MS[Component.MEASUREMENT] ) return F
[docs] def calculate_p(self, dof, F): """Calculate P-Values.""" P = dict() P[Component.OPERATOR] = stats.f.sf( F[Component.OPERATOR], dof[Component.OPERATOR], dof[Component.OPERATOR_BY_PART], ) P[Component.PART] = stats.f.sf( F[Component.PART], dof[Component.PART], dof[Component.OPERATOR_BY_PART] ) P[Component.OPERATOR_BY_PART] = stats.f.sf( F[Component.OPERATOR_BY_PART], dof[Component.OPERATOR_BY_PART], dof[Component.MEASUREMENT], ) return P