def __init__(self): QoIMetric.__init__(self, "Correctness") self.updatecounter = 0 self.rewardAndPunishment = RewardAndPunishment(20) self.goal = 1 # always want 100% correctness self.min = 1 self.mean = 1 self.unit = "http://purl.oclc.org/NET/muo/ucum/unit/fraction/percent"
def __init__(self): QoIMetric.__init__(self, "Age") self.lastUpdate = None self.weight = 0.99 self.nulldelta = timedelta(seconds=0) self.rewardAndPunishment = RewardAndPunishment(5) self.datatype = "time" self.updatecounter = 1 self.unit = "http://purl.oclc.org/NET/muo/ucum/unit/time/second"
class Age(QoIMetric): """docstring for Age""" def __init__(self): QoIMetric.__init__(self, "Age") self.lastUpdate = None self.weight = 0.99 self.nulldelta = timedelta(seconds=0) self.rewardAndPunishment = RewardAndPunishment(5) self.datatype = "time" self.updatecounter = 1 self.unit = "http://purl.oclc.org/NET/muo/ucum/unit/time/second" def updateDescription(self): # get data from sensor description # self.maxAge = timedelta(seconds=self.repsys.description.updateInterval) self.annotatedAge = self.repsys.description.updateInterval # + 0.05 * self.repsys.description.updateInterval def update(self, data): self.updateDescription() # special case when no fields are in data # (fault recovery is not ready yet) if len(data.fields) == 0: self.rewardAndPunishment.update(False) self.absoluteValue = float("inf") self.ratedValue = self.rewardAndPunishment.value() return ts = self.repsys.timestamp self.updatecounter += 1 samplingTime = datetime.datetime.strptime(data[data.fields[0]].observationSamplingTime, AbstractClock.parserformat) age = (samplingTime - ts).total_seconds() # print "age:", age, "ts", ts, "sampling", samplingTime if self.lastUpdate == None: self.lastUpdate = ts self.rewardAndPunishment.update(True) self.absoluteValue = age self.ratedValue = 1.0 self.min = age self.mean = age else: # delta = ts - self.lastUpdate self.lastUpdate = ts if data.recovered: self.rewardAndPunishment.update(False) else: self.rewardAndPunishment.update(age <= self.annotatedAge) # delay = delta.days * 86400 + delta.seconds self.absoluteValue = age self.ratedValue = self.rewardAndPunishment.value() age = float(age) self.min = min(self.min, age) self.mean = ((self.updatecounter - 1) * self.mean) / self.updatecounter + age / self.updatecounter ageReturn = JSONObject() ageReturn.absoluteValue = self.absoluteValue ageReturn.ratedValue = self.ratedValue ageReturn.unit = self.unit return (self.name, ageReturn)
class Correctness(QoIMetric): """docstring for Correctness""" def __init__(self): QoIMetric.__init__(self, "Correctness") self.updatecounter = 0 self.rewardAndPunishment = RewardAndPunishment(20) self.goal = 1 # always want 100% correctness self.min = 1 self.mean = 1 self.unit = "http://purl.oclc.org/NET/muo/ucum/unit/fraction/percent" def update(self, data): self.updatecounter += 1 # special case when no fields are in data # (fault recovery is not ready yet) if len(data.fields) == 0: self.rewardAndPunishment.update(False) self.absoluteValue = float("inf") self.ratedValue = self.rewardAndPunishment.value() return wrongFieldList = [] for field in data.fields: if field not in data: wrongFieldList.append(field) continue dataTypeStr = self.repsys.description.field[field].dataType dataType = utils.getType(dataTypeStr) minValue, maxValue = self.getMinMaxValue(field, data) value = data[field].value # print "field:", field, "value:", value, "min:", minValue, "max:", maxValue, "dataType:", dataTypeStr, dataType, "value type:", type(value) if minValue and maxValue: if dataTypeStr == "datetime.datetime": minValue = datetime.datetime.strptime(minValue, AbstractClock.parserformat) maxValue = datetime.datetime.strptime(maxValue, AbstractClock.parserformat) else: maxValue = dataType(maxValue) minValue = dataType(minValue) # everything might be a string => first check for type, then try to cast, afterwards check min and max wrongValue = False if not isinstance(value, dataType): # type(value) is not dataType: try: # special handling for datetime as format is needed if dataTypeStr == "datetime.datetime": value = datetime.datetime.strptime(value, self.repsys.description.field[field].format) else: value = dataType(value) except ValueError: wrongFieldList.append(field) wrongValue = True if not wrongValue: # now check if value is within min max interval if minValue and minValue is not "": if value < minValue: wrongFieldList.append(field) elif maxValue and maxValue is not "": if value > maxValue: wrongFieldList.append(field) # print "Correctness for", self.repsys.description.fullSensorID, len(wrongFieldList), value, minValue, maxValue nrWrongFields = len(wrongFieldList) if nrWrongFields > 0: L.d("Correctness wrong fields:", nrWrongFields, "(", ",".join(wrongFieldList), ")") if data.recovered or (nrWrongFields >= 1): self.rewardAndPunishment.update(False) else: self.rewardAndPunishment.update(True) self.ratedValue = self.rewardAndPunishment.value() self.absoluteValue = 1 - nrWrongFields / len(data.fields) self.min = min(self.min, self.absoluteValue) self.mean = ((self.updatecounter - 1) * self.mean) / self.updatecounter + float( self.absoluteValue) / self.updatecounter correctness = JSONObject() correctness.wrongFields = wrongFieldList correctness.absoluteValue = self.absoluteValue correctness.ratedValue = self.ratedValue correctness.unit = self.unit # print "correctness:", self.ratedValue, self.absoluteValue return (self.name, correctness) def getMinMaxValue(self, fieldname, data): # print "getMinMaxValue", fieldname#, data # print self.repsys.description.field[fieldname] if "min" in self.repsys.description.field[fieldname]: minValue = self.repsys.description.field[fieldname].min minValue = self.getValue(minValue, data) else: minValue = None if "max" in self.repsys.description.field[fieldname]: maxValue = self.repsys.description.field[fieldname].max maxValue = self.getValue(maxValue, data) else: maxValue = None return minValue, maxValue def getValue(self, minMaxValue, data): try: if minMaxValue.startswith('@'): # find out in which field value is annotated name = minMaxValue[1:] return data[name].value return minMaxValue except: return minMaxValue
class Latency(QoIMetric): """docstring for Latency""" def __init__(self): QoIMetric.__init__(self, "Latency") self.lastUpdate = None self.weight = 0.99 self.nulldelta = timedelta(seconds=0) self.rewardAndPunishment = RewardAndPunishment(5) self.datatype = "time" self.updatecounter = 1 self.unit = "http://purl.oclc.org/NET/muo/ucum/unit/time/second" def updateDescription(self): # get data from sensor description self.maxAge = timedelta(seconds=self.repsys.description.updateInterval) self.definedAge = self.repsys.description.updateInterval def update(self, data): self.updateDescription() # special case when no fields are in data # (fault recovery is not ready yet) if len(data.fields) == 0: self.rewardAndPunishment.update(False) self.absoluteValue = float("inf") self.ratedValue = self.rewardAndPunishment.value() return ts = self.repsys.timestamp self.updatecounter += 1 latency = data.latency annotatedLatency = self.repsys.description.maxLatency if self.lastUpdate is None: self.lastUpdate = ts self.rewardAndPunishment.update(True) self.absoluteValue = latency self.ratedValue = 1.0 self.min = latency self.mean = latency else: self.lastUpdate = ts if data.recovered: self.rewardAndPunishment.update(False) else: self.rewardAndPunishment.update(annotatedLatency > latency) self.absoluteValue = latency self.ratedValue = self.rewardAndPunishment.value() self.min = min(self.min, latency) self.mean = ((self.updatecounter - 1) * self.mean) / self.updatecounter + latency / self.updatecounter lat = JSONObject() lat.absoluteValue = self.absoluteValue lat.ratedValue = self.ratedValue lat.unit = self.unit return (self.name, lat)
class Completeness(QoIMetric): """docstring for Completeness""" def __init__(self): QoIMetric.__init__(self, "Completeness") self.goal = None self.rewardAndPunishment = RewardAndPunishment(5) self.updatecounter = 1 self.unit = "http://purl.oclc.org/NET/muo/ucum/physical-quality/number" def update(self, data): # special case when no fields are in data # (fault recovery is not ready yet) if len(data.fields) == 0: self.rewardAndPunishment.update(False) self.absoluteValue = float("inf") self.ratedValue = self.rewardAndPunishment.value() return # look for expected fields in sensor description, look only for non optional fields fields = self.repsys.description.fields fields = [x for x in fields if not self.repsys.description.field[x].optional] receivedFields = data.fields # check if expected and received identical, how to handle received fields with no values? nrOfMissingFields = 0 missingFields = set() if set(fields).difference(set(receivedFields)): # lists are different missingFields = set(fields).difference(set(receivedFields)) nrOfMissingFields = len(missingFields) # now go through all fields and check for NULL, NA,... nrOfWrongFields = 0 wrongFields = set() wrongValues = ['None', 'Null', '', 'NA'] #TODO make the list of wrong values configurable for field in data.fields: if field in data: value = data[field].value if value is None or value in wrongValues: nrOfWrongFields += 1 wrongFields.add(field) else: nrOfWrongFields += 1 wrongFields.add(field) if nrOfMissingFields > 0: L.d("Completeness missing fields:", nrOfMissingFields, "(", ",".join(missingFields), ")") if nrOfWrongFields > 0: L.d("Completeness wrong fields:", nrOfWrongFields, "(", ",".join(wrongFields), ")") length = len(self.repsys.description.fields) currentLength = length - nrOfMissingFields - nrOfWrongFields self.updatecounter += 1 if not self.goal: self.goal = length self.min = float(length) self.mean = float(length) # return (length, self.rewardAndPunishment.value()) else: self.min = min(self.min, currentLength) self.mean = ((self.updatecounter - 1) * self.mean) / self.updatecounter + float( currentLength) / self.updatecounter if data.recovered: self.rewardAndPunishment.update(False) else: self.rewardAndPunishment.update(self.goal == currentLength) self.absoluteValue = currentLength self.ratedValue = self.rewardAndPunishment.value() completeness = JSONObject() completeness.missingFields = list(missingFields | wrongFields) completeness.absoluteValue = self.absoluteValue completeness.ratedValue = self.ratedValue completeness.unit = self.unit # print completeness.dumps() # print "completeness:", self.name, completeness # print (self.name, missingFields) return (self.name, completeness)
def __init__(self): QoIMetric.__init__(self, "Completeness") self.goal = None self.rewardAndPunishment = RewardAndPunishment(5) self.updatecounter = 1 self.unit = "http://purl.oclc.org/NET/muo/ucum/physical-quality/number"