Coverage for gpkit/interactive/references.py: 95%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

61 statements  

1"Code to make variable references plots" 

2 

3import os 

4import shutil 

5import webbrowser 

6from collections import defaultdict 

7 

8 

9# pylint:disable=too-many-locals 

10def referencesplot(model, *, openimmediately=True): 

11 """Makes a references plot. 

12 

13 1) Creates the JSON file for a d3 references plot 

14 2) Places it and the corresponding HTML file in the working directory 

15 3) (optionally) opens that HTML file up immediately in a web browser 

16 

17 """ 

18 imports = {} 

19 totalv_ss = defaultdict(dict) 

20 for constraint in model.flat(): 

21 for varkey in constraint.vks: 

22 vlineage = varkey.lineagestr() 

23 clineage = constraint.lineagestr() 

24 if not vlineage: 

25 vlineage = "%s [%s]" % (varkey, varkey.unitstr()) 

26 for lin in (clineage, vlineage): 

27 if lin not in imports: 

28 imports[lin] = set() 

29 if vlineage != clineage: 

30 imports[clineage].add(vlineage) 

31 if constraint.v_ss: 

32 totalv_ss[clineage] += constraint.v_ss 

33 

34 def clean_lineage(lineage, clusterdepth=2): 

35 prelineage = ".".join(lineage.split(".")[:clusterdepth]) 

36 last = "0".join(lineage.split(".")[clusterdepth:]) 

37 return "model."+prelineage + "." + last 

38 

39 lines = ['jsondata = ['] 

40 for lineage, limports in imports.items(): 

41 name, short = clean_lineage(lineage), lineage.split(".")[-1] 

42 limports = map(clean_lineage, limports) 

43 lines.append( 

44 ' {"name":"%s","fullname":"%s","shortname":"%s","imports":%s},' 

45 % (name, lineage, short, repr(list(limports)).replace("'", '"'))) 

46 lines[-1] = lines[-1][:-1] 

47 lines.append("]") 

48 

49 if totalv_ss: 

50 def get_total_senss(clineage, vlineage, normalize=False): 

51 v_ss = totalv_ss[clineage] 

52 num = sum(abs(ss) for vk, ss in v_ss.items() 

53 if vk.lineagestr() == vlineage) 

54 if not normalize: 

55 return num 

56 return num/sum(abs(ss) for ss in v_ss.values()) 

57 lines.append("globalsenss = {") 

58 for clineage, limports in imports.items(): 

59 if not limports: 

60 continue 

61 limports = {vl: get_total_senss(clineage, vl) for vl in limports} 

62 lines.append(' "%s": %s,' % 

63 (clineage, repr(limports).replace("'", '"'))) 

64 lines[-1] = lines[-1][:-1] 

65 lines.append("}") 

66 lines.append("normalizedsenss = {") 

67 for clineage, limports in imports.items(): 

68 if not limports: 

69 continue 

70 limports = {vl: get_total_senss(clineage, vl, normalize=True) 

71 for vl in limports} 

72 lines.append(' "%s": %s,' % 

73 (clineage, repr(limports).replace("'", '"'))) 

74 lines[-1] = lines[-1][:-1] 

75 lines.append("}") 

76 

77 with open("referencesplot.json", "w") as f: 

78 f.write("\n".join(lines)) 

79 

80 htmlfile = "referencesplot.html" 

81 if not os.path.isfile(htmlfile): 

82 shutil.copy(os.path.join(os.path.dirname(__file__), htmlfile), htmlfile) 

83 

84 if openimmediately: 

85 webbrowser.open("file://" + os.path.join(os.getcwd(), htmlfile), 

86 autoraise=True)