def genfsms(self,meter=None):
		"""Generate FSM images. Requires networkx and GraphViz."""

		if (hasattr(self,'allParses')):
			name=self.getName()

			import networkx as nx
			m2int={'w':'0','s':'1'}

			gs={}
			gs['weight']=['str_weight']
			gs['stress']=['str_stress']
			gs['stressweight']=['str_stress','str_weight']
			gs['meterweight']=['str_meter','str_weight']
			gs['meterstress']=['str_meter','str_stress']
			#gs['numseg']=['str_numseg']
			#gs['metershape']=['str_meter','getShape']
			gs['meter']=['str_meter']
			#gs['shape']=['str_shape']
			#gs['weightshape']=['str_weight','str_shape']

			Gs={}

			if len(self.bestParses(meter=meter))==1: # if this is a direct input or a single line
				parses=[]
				for _parses in self.allParses():
					parses+=_parses
				use_labels = True
			else:
				parses=self.bestParses()
				use_labels = False

			for gtype in gs.keys():
				G=nx.DiGraph()
				sumweight={}
				nodetypes=[]
				linelens=[]

				for parse in parses:
					node1=None
					node2=None

					posnum=0
					linelens.append(len(parse.positions))
					for pos in parse.positions:
						has_viol = bool(sum(pos.constraintScores.values()))
						for unit in pos.slots:
							spelling=unit.children[0].str_orth()
							posnum+=1
							if hasattr(being,'line_maxsylls'):
								if posnum>int(being.line_maxsylls):
									break

							nodestr=""
							unit.meter=pos.meterVal
							for strcaller in sorted(gs[gtype]):

								z=unit.findattr(strcaller,'children')
								if type(z)==type([]):
									nodestr+="".join( [str(x()) for x in z] )
								else:
									nodestr+=str(z())

							if not nodestr: continue
							if use_labels:
								nodestr+='_'+ (spelling.upper() if unit.meter=='s' else spelling.lower())
							nodestr=str(posnum)+"_"+str(nodestr)
							if (not nodestr in nodetypes):
								nodetypes.append(nodestr)
							#node=str(posnum)+"_"+str(nodestr)
							node=nodestr

							if not node1:
								node1=node
								continue
							node2=node

							if G.has_edge(node1,node2):
								G[node1][node2]['weight']+=1
							else:
								G.add_edge(node1,node2,weight=1)
							try:
								sumweight[(str(node1)[0],str(node2)[0])]+=1
							except KeyError:
								sumweight[(str(node1)[0],str(node2)[0])]=1

							node1=node2

				if not linelens: continue

				maxlinesize=6
				nodes=G.nodes()
				#for n1,nbrs in G.adjacency_iter():
				#	for n2,eattr in nbrs.items():
				for n1,n2,eattr in G.edges(data=True):
					count=G[n1][n2]['weight']
					G[n1][n2]['weight']=count/sumweight[(n1[0],n2[0])]
					strfreq=str(G[n1][n2]['weight']*100)
					if len(strfreq)>3:
						strfreq=strfreq[0:3]
					G[n1][n2]['label']=str(count)+" ["+str(strfreq)+"%]"
					G[n1][n2]['fontsize']=10
					G[n1][n2]['penwidth']=G[n1][n2]['weight']*maxlinesize
					G.node[n1]['width']=1
					G.node[n2]['width']=1
					G[n1][n2]['weight']=0
					#G[n1][n2]['style']="setlinewidth("+str(int(G[n1][n2]['weight']*maxlinesize)+1)+")"
					#print G[n1][n2]['style']
					#G[n1][n2]['arrowhead']='none'

				import math
				"""avglinelen=int(max(linelens))
				for n in range(2,avglinelen):
					for ntype in nodetypes:
						node1=str(n-1)+"_"+ntype
						node2=str(n)+"_"+ntype
						if not G.has_edge(node1,node2):
							G.add_edge(node1,node2,weight=0,penwidth=0,color='white')
				"""

				fn='results/fsms/'+str(gtype)+"."+name+'.png'
				print ">> saved: "+fn+""
				#plt.savefig(fn)
				#nx.write_dot(G,fn)
				pyd=nx.to_pydot(G)
				pyd.set_rankdir('LR')

				for node in pyd.get_node_list():
					node.set_orientation('portrait')

				import prosodic as p
				fnfn=os.path.join(p.dir_prosodic,fn)
				_path=os.path.split(fnfn)[0]
				if not os.path.exists(_path):
					os.makedirs(_path)
				pyd.write_png(fnfn, prog='dot')

		else:
			if not self.children:
				return ""
			elif type(self.children[0])==type([]):
				return []
			else:
				[child.genfsms() for child in self.children]
Generate FSM images. Requires networkx and GraphViz.