def testFindCorrectRanges(self): sd = SampleDirectory(self.theDir) st = sd["0"] U = st[("line1", "U")] self.assert_(U.isVector()) p = st[("line1", "p")] self.assert_(not p.isVector()) self.assertEqual(p.domain(), (0., 3.)) self.assertEqual(p.range(), (0., 1.))
def testUsePrePostfix(self): sd = SampleDirectory(self.theDir, prefixes=["pre"], postfixes=["post"]) self.assertEqual(len(sd), 2) self.assertEqual(len(sd.lines()), 2) self.assertEqual(len(sd.values()), 8) self.assertEqual(len(sd.getData()), 15) st = sd["0"] p = st[("line2", "p_post")] p2 = st[("line2", "pre_p")]
def testFindCorrectNames(self): sd = SampleDirectory(self.theDir, valueNames=["p", "p2", "p3"], linePattern=".*prefix_([^.]+).*", needsExtension=False) self.assertEqual(len(sd), 2) self.assertEqual(len(sd.lines()), 2) self.assertEqual(len(sd.values()), 3) self.assertEqual(len(sd.getData()), 6)
def testFindCorrectRanges(self): sd = SampleDirectory(self.theDir) st = sd["0"] U = st[("line1", "U")] p = st[("line1", "p")] spread = U() + p() spread2 = p() spread2.title = "duplicate" spread += spread2 spread.writeCSV(path.join(self.theDir, "sample.csv"))
def testFindCorrectNames(self): sd = SampleDirectory(self.theDir) self.assertEqual(len(sd), 2) self.assertEqual(len(sd.lines()), 2) self.assertEqual(len(sd.values()), 5) self.assertEqual(len(sd.getData()), 9)
def testFailOnWrongData(self): sd = SampleDirectory(self.theDir) st = sd["0"] self.assertRaises(KeyError, st.__getitem__, ("line2", "p3"))
def testGetTimes(self): sd = SampleDirectory(self.theDir) st = sd["0"] self.assertRaises(KeyError, sd.__getitem__, "3")
def run(self): if self.opts.isDistribution: if self.opts.valueNames or self.opts.linePattern: self.error( "The option --is-distribution can not be used with --pattern-for-line or --default-value-names" ) # self.opts.valueNames="normalized,raw" self.opts.linePattern = ".+istribution_(.+)" self.opts.needsExtension = False # remove trailing slashif present if self.opts.dirName[-1] == path.sep: self.opts.dirName = self.opts.dirName[:-1] usedDirName = self.opts.dirName.replace("/", "_") if self.opts.valueNames == None: usedValueNames = None else: usedValueNames = self.opts.valueNames.split(","), samples = SampleDirectory(self.parser.getArgs()[0], dirName=self.opts.dirName, postfixes=self.opts.fieldPostfix, prefixes=self.opts.fieldPrefix, valueNames=usedValueNames, namesFromFirstLine=self.opts.isDistribution, linePattern=self.opts.linePattern, needsExtension=self.opts.needsExtension) reference = None if self.opts.reference and self.opts.referenceCase: self.error( "Options --reference-directory and --reference-case are mutual exclusive" ) if (self.opts.csvFile or self.opts.excelFile or self.opts.pandasData or self.opts.numpyData) and (self.opts.compare or self.opts.metrics): self.error( "Options --csv-file/--excel-file/--pandas-data/--numpy-data and --compare/--metrics are mutual exclusive" ) if self.opts.reference: reference = SampleDirectory(self.parser.getArgs()[0], dirName=self.opts.reference, postfixes=self.opts.fieldPostfix, prefixes=self.opts.fieldPrefix) elif self.opts.referenceCase: reference = SampleDirectory(self.opts.referenceCase, dirName=self.opts.dirName, postfixes=self.opts.fieldPostfix, prefixes=self.opts.fieldPrefix) if reference: if path.samefile(reference.dir, samples.dir): self.error("Used sample directory", samples.dir, "and reference directory", reference.dir, "are the same") lines = samples.lines() times = samples.times if self.opts.info: if not self.opts.silent: print_("Times : ", samples.times) print_("Lines : ", samples.lines()) print_("Fields: ", list(samples.values())) self.setData({ 'times': samples.times, 'lines': samples.lines(), 'values': list(samples.values()) }) if reference: if not self.opts.silent: print_("\nReference Data:") print_("Times : ", reference.times) print_("Lines : ", reference.lines()) print_("Fields: ", list(reference.values())) self.setData({ 'reference': { 'times': samples.times, 'lines': samples.lines(), 'values': list(samples.values()) } }) return 0 if self.opts.line == None: # error("At least one line has to be specified. Found were",samples.lines()) self.opts.line = lines else: for l in self.opts.line: if l not in lines: error("The line", l, "does not exist in", lines) if self.opts.latestTime: if self.opts.time: self.opts.time.append(samples.times[-1]) else: self.opts.time = [samples.times[-1]] if self.opts.maxTime or self.opts.minTime: if self.opts.time: error("Times", self.opts.time, "and range [", self.opts.minTime, ",", self.opts.maxTime, "] set: contradiction") self.opts.time = [] if self.opts.maxTime == None: self.opts.maxTime = 1e20 if self.opts.minTime == None: self.opts.minTime = -1e20 for t in times: if float(t) <= self.opts.maxTime and float( t) >= self.opts.minTime: self.opts.time.append(t) if len(self.opts.time) == 0: error("No times in range [", self.opts.minTime, ",", self.opts.maxTime, "] found: ", times) elif self.opts.time: iTimes = self.opts.time self.opts.time = [] for t in iTimes: if t in samples.times: self.opts.time.append(t) elif self.opts.fuzzyTime: tf = float(t) use = None dist = 1e20 for ts in samples.times: if abs(tf - float(ts)) < dist: use = ts dist = abs(tf - float(ts)) if use and use not in self.opts.time: self.opts.time.append(use) else: pass # self.warning("Time",t,"not found in the sample-times. Use option --fuzzy") if self.opts.tolerantReferenceTime: if self.opts.referenceTime: self.error( "--tolerant-reference-time and --reference-time can't be used at the same time" ) refTimes = {} for t in self.opts.time: dist = 1e20 for rt in reference.times: if abs(float(t) - float(rt)) < dist: refTimes[t] = rt dist = abs(float(t) - float(rt)) plots = [] oPlots = [] rPlots = [] if self.opts.mode == "separate": if self.opts.time == None: self.opts.time = samples.times if self.opts.field == None: self.opts.field = list(samples.values()) if self.opts.line == None: self.opts.line = samples.lines() for t in self.opts.time: for f in self.opts.field: for l in self.opts.line: plot = samples.getData(line=[l], value=[f], time=[t], scale=(self.opts.scaleXAxis, self.opts.scaleData), offset=(self.opts.offsetXAxis, self.opts.offsetData)) oPlots.append(plot[:]) if reference: rT = [t] if self.opts.referenceTime: rT = [self.opts.referenceTime] elif self.opts.tolerantReferenceTime: rT = [refTimes[t]] p = reference.getData( line=[l], value=[f], time=rT, note=self.opts.refprefix + " ", scale=(self.opts.scaleReferenceXAxis, self.opts.scaleReferenceData), offset=(self.opts.offsetReferenceXAxis, self.opts.offsetReferenceData)) rPlots.append(p) plot += p plots.append(plot) elif self.opts.mode == "timesInOne": if self.opts.field == None: self.opts.field = list(samples.values()) if self.opts.line == None: self.opts.line = samples.lines() for f in self.opts.field: for l in self.opts.line: plot = samples.getData(line=[l], value=[f], time=self.opts.time) oPlots.append(plot[:]) if reference: rT = self.opts.time if self.opts.referenceTime: rT = [self.opts.referenceTime] elif self.opts.tolerantReferenceTime: rT = [refTimes[t]] p = reference.getData(line=[l], value=[f], time=rT, note=self.opts.refprefix + " ") rPlots.append(p) plot += p plots.append(plot) elif self.opts.mode == "fieldsInOne": if self.opts.scaled and not self.opts.scaleAll: warning("In mode '", self.opts.mode, "' all fields are scaled to the same value") self.opts.scaleAll = True if self.opts.time == None: self.opts.time = samples.times if self.opts.line == None: self.opts.line = samples.lines() for t in self.opts.time: for l in self.opts.line: plot = samples.getData(line=[l], value=self.opts.field, time=[t]) oPlots.append(plot[:]) if reference: rT = t if self.opts.referenceTime: rT = self.opts.referenceTime elif self.opts.tolerantReferenceTime: rT = refTimes[t] p = reference.getData(line=[l], value=self.opts.field, time=[rT], note=self.opts.refprefix + " ") rPlots.append(p) plot += p plots.append(plot) elif self.opts.mode == "linesInOne": if self.opts.field == None: self.opts.field = list(samples.values()) if self.opts.time == None: self.opts.time = samples.times for f in self.opts.field: for t in self.opts.time: plot = samples.getData(line=self.opts.line, value=[f], time=[t]) oPlots.append(plot[:]) if reference: rT = t if self.opts.referenceTime: rT = self.opts.referenceTime elif self.opts.tolerantReferenceTime: rT = refTimes[t] p = reference.getData(line=self.opts.line, value=[f], time=[rT], note=self.opts.refprefix + " ") rPlots.append(p) plot += p plots.append(plot) elif self.opts.mode == "complete": if self.opts.scaled and not self.opts.scaleAll: warning("In mode '", self.opts.mode, "' all fields are scaled to the same value") self.opts.scaleAll = True plot = samples.getData(line=self.opts.line, value=self.opts.field, time=self.opts.time) oPlots.append(plot[:]) if reference: rT = self.opts.time if self.opts.referenceTime: rT = [self.opts.referenceTime] elif self.opts.tolerantReferenceTime: rT = [refTimes[t]] p = reference.getData(line=self.opts.line, value=self.opts.field, time=rT, note=self.opts.refprefix + " ") plot += p rPlots.append(p) plots.append(plot) xMin, xMax = None, None if self.opts.scaleDomain: if self.opts.domainMin or self.opts.domainMax: self.error( "--scale-domain used. Can't use --domain-minimum or --domain-maximum" ) xMin, xMax = 1e40, -1e40 for p in plots: for d in p: mi, mx = d.domain() xMin = min(xMin, mi) xMax = max(xMax, mx) else: xMin, xMax = self.opts.domainMin, self.opts.domainMax if self.opts.scaled: if self.opts.scaleAll: vRange = None else: vRanges = {} for p in plots: for d in p: mi, ma = d.range(component=self.opts.component) nm = d.name if not self.opts.scaleAll: if nm in vRanges: vRange = vRanges[nm] else: vRange = None if vRange == None: vRange = mi, ma else: vRange = min(vRange[0], mi), max(vRange[1], ma) if not self.opts.scaleAll: vRanges[nm] = vRange result = "set term png\n" plots = [p for p in plots if len(p) > 0] if len(plots) < 1: self.error("No plots produced. Nothing done") for p in plots: if len(p) < 1: continue name = "" if self.opts.namePrefix: name += self.opts.namePrefix + "_" name += usedDirName title = None tIndex = times.index(p[0].time()) # name+="_"+string.join(self.opts.line,"_") if self.opts.mode == "separate": name += "_%s" % (p[0].line()) if self.opts.indexInsteadOfTime: name += "_%s_%04d" % (p[0].name, tIndex) else: name += "_%s_t=%f" % (p[0].name, float(p[0].time())) title = "%s at t=%f on %s" % (p[0].name, float( p[0].time()), p[0].line()) elif self.opts.mode == "timesInOne": name += "_%s" % (p[0].line()) if self.opts.time != None: name += "_" + "_".join(["t=" + t for t in self.opts.time]) name += "_%s" % p[0].name title = "%s on %s" % (p[0].name, p[0].line()) elif self.opts.mode == "fieldsInOne": name += "_%s" % (p[0].line()) if self.opts.field != None: name += "_" + string.join(self.opts.field, "_") if self.opts.time != None: name += "_" + "_".join(["t=" + t for t in self.opts.time]) name += "_%04d" % tIndex title = "t=%f on %s" % (float(p[0].time()), p[0].line()) elif self.opts.mode == "linesInOne": name += "_%s" % (p[0].name) if self.opts.line != None: name += "_" + string.join(self.opts.line, "_") if self.opts.indexInsteadOfTime: name += "_%04d" % tIndex else: name += "_t=%f" % float(p[0].time()) title = "%s at t=%f" % (p[0].name, float(p[0].time())) elif self.opts.mode == "complete": pass name += ".png" if self.opts.pictureDest: name = path.join(self.opts.pictureDest, name) if self.opts.cleanFilename: name = cleanFilename(name) result += 'set output "%s"\n' % name if title != None: result += 'set title "%s"\n' % title.replace("_", "\\_") result += "plot " if self.opts.scaled: if not self.opts.scaleAll: vRange = vRanges[p[0].name] # only scale if extremas are sufficiently different if abs(vRange[0] - vRange[1]) > 1e-5 * max( abs(vRange[0]), abs(vRange[1])) and max( abs(vRange[0]), abs(vRange[1])) > 1e-10: yRange = "[%g:%g] " % vRange else: yRange = "[]" else: yRange = "[]" if xMin or xMax: xRange = "[" if xMin: xRange += str(xMin) xRange += ":" if xMax: xRange += str(xMax) xRange += "]" else: xRange = "[]" if self.opts.scaled or xMin or xMax: result += xRange + yRange first = True for d in p: if first: first = False else: result += ", " colSpec = d.index + 1 if d.isVector(): if self.opts.component != None: colSpec = d.index + 1 + self.opts.component else: colSpec = "(sqrt($%d**2+$%d**2+$%d**2))" % ( d.index + 1, d.index + 2, d.index + 3) # result+='"%s" using 1:%s ' % (d.file,colSpec) def makeCol(spec, sc, off): if type(spec) == str: pre = "" else: pre = "$" spec = str(spec) if sc == 1: if off == 0: return spec else: return "(%s%s+%f)" % (pre, spec, off) else: if off == 0: return "(%s%s*%f)" % (pre, spec, sc) else: return "(%s%s*%f+%f)" % (pre, spec, sc, off) result += '"%s" using %s:%s ' % ( d.file, makeCol(1, d.scale[0], d.offset[0]), makeCol(colSpec, d.scale[1], d.offset[1])) title = d.note if self.opts.mode == "separate": title += "" elif self.opts.mode == "timesInOne": title += "t=%f" % float(d.time()) elif self.opts.mode == "fieldsInOne": title += "%s" % d.name elif self.opts.mode == "linesInOne": title += "t=%f" % float(d.time()) elif self.opts.mode == "complete": title += "%s at t=%f" % (d.name, float(d.time())) if len(self.opts.line) > 1: title += " on %s" % d.line() if title == "": result += "notitle " else: result += 'title "%s" ' % title.replace("_", "\\_") result += "with %s " % self.opts.style result += "\n" if self.opts.csvFile or self.opts.excelFile or self.opts.pandasData or self.opts.numpyData: tmp = sum(plots, []) c = tmp[0]() for p in tmp[1:]: try: c += p() except WrongDataSize: if self.opts.resampleReference: sp = p() for n in sp.names()[1:]: data = c.resample(sp, n, extendData=self.opts.extendData) try: c.append(n, data) except ValueError: c.append(self.opts.refprefix + " " + n, data) else: self.warning("Try the --resample-option") raise if self.opts.csvFile: c.writeCSV(self.opts.csvFile) if self.opts.excelFile: c.getData().to_excel(self.opts.excelFile) if self.opts.pandasData: self.setData({ "series": c.getSeries(), "dataFrame": c.getData() }) if self.opts.numpyData: self.setData({"data": c.data.copy()}) elif self.opts.compare or self.opts.metrics: statData = {} if self.opts.compare: statData["compare"] = {} if self.opts.metrics: statData["metrics"] = {} for p in self.opts.line: if self.opts.compare: statData["compare"][p] = {} if self.opts.metrics: statData["metrics"][p] = {} oPlots = [item for sublist in oPlots for item in sublist] rPlots = [item for sublist in rPlots for item in sublist] if len(rPlots) != len(oPlots) and self.opts.compare: self.error("Number of original data sets", len(oPlots), "is not equal to the reference data sets", len(rPlots)) if len(rPlots) == 0 and self.opts.metrics: rPlots = [None] * len(oPlots) for o, r in zip(oPlots, rPlots): data = o(scaleData=self.opts.scaleData, offsetData=self.opts.offsetData, scaleX=self.opts.scaleXAxis, offsetX=self.opts.offsetXAxis) if self.opts.compare: if o.name != r.name or (o.index != r.index and not self.opts.indexTolerant): self.error( "Data from original", o.name, o.index, "and reference", r.name, r.index, "do not match. Try --index-tolerant-compare if you're sure that the data is right" ) ref = r(scaleData=self.opts.scaleReferenceData, offsetData=self.opts.offsetReferenceData, scaleX=self.opts.scaleReferenceXAxis, offsetX=self.opts.offsetReferenceXAxis) else: ref = None for i, n in enumerate(data.names()): if i == 0: continue indexName = o.name if n.split(" ")[-1] != indexName: indexName = n.split(" ")[-1] if self.opts.metrics: if not self.opts.silent: print_("Metrics for", indexName, "(Path:", o.file, ")") result = data.metrics(data.names()[i], minTime=self.opts.minTime, maxTime=self.opts.maxTime) statData["metrics"][o.line()][indexName] = result if not self.opts.silent: print_(" Min :", result["min"]) print_(" Max :", result["max"]) print_(" Average :", result["average"]) print_(" Weighted average :", result["wAverage"]) if not self.opts.compare: print_("Data size:", data.size()) print_(" Time Range :", result["tMin"], result["tMax"]) if self.opts.compare: oname = data.names()[i] if self.opts.referenceTime or self.opts.tolerantReferenceTime: oname = ref.names()[i] if not self.opts.silent: print_("Comparing", indexName, "with name", oname, "(Path:", r.file, ")", end="") if self.opts.compareOnOriginal: if not self.opts.silent: print_("on original data points") result = data.compare(ref, data.names()[i], otherName=oname, common=self.opts.commonRange, minTime=self.opts.minTime, maxTime=self.opts.maxTime) else: if not self.opts.silent: print_("on reference data points") result = ref.compare(data, oname, otherName=data.names()[i], common=self.opts.commonRange, minTime=self.opts.minTime, maxTime=self.opts.maxTime) statData["compare"][o.line()][indexName] = result if not self.opts.silent: print_(" Max difference :", result["max"], "(at", result["maxPos"], ")") print_(" Average difference :", result["average"]) print_(" Weighted average :", result["wAverage"]) print_("Data size:", data.size(), "Reference:", ref.size()) if not self.opts.metrics: print_(" Time Range :", result["tMin"], result["tMax"]) if not self.opts.silent: print_() self.setData(statData) else: dest = sys.stdout if self.opts.gnuplotFile: dest = open(self.opts.gnuplotFile, "w") dest.write(result)