class Freeze(ScenarioBase): def __init__(self): ScenarioBase.__init__(self) self.typeident = 'SFRE' self.version = '0.1' self.additional_attributes = ['intensity'] self.footprint = Footprint('freeze100', self.additional_attributes) def pre_model(self, n, layerid=0, iteration=0): ScenarioBase.pre_model(self, n, layerid, iteration) # apply footprint schema = n.layers[layerid].layerid.schema if schema is None: schema = 'asset_engine' nodetablename = n.layers[layerid].layerid.nodetablename if nodetablename is not None: nodetablename = schema + '.' + nodetablename self.footprint.apply(nodetablename, n.layergraphs[layerid]) return 0
def dispatch(self, request, *args, **kwargs): if self.preProcessPage(request, **kwargs): ###import json #import urllib2 #urlStr = 'http://gemecd.org:8080/geoserver/gemecd/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=gemecd:geoarchivelocations&maxFeatures=5000&outputFormat=json' #jsonStr = urllib2.urlopen(urlStr).read() #pass this string to leaflet L.geoJson(geojsonFeature).addTo(map); ###jsonData = json.loads(jsonStr) #only of you want to process the GeoJSON in Python ix = 15 # network manager page id self.page_context['ix'] = str(ix) tabmode = 'list' self.page_context['init_code'] = '' try: if request.REQUEST['tab'] == 'map': tabmode='map' if request.REQUEST['tab'] == 'list': tabmode='list' if request.REQUEST['tab'] == 'topo': tabmode='map' self.page_context['init_code'] += 'toggle();' except: pass self.page_context['tabmode'] = tabmode distrib = True try: if request.REQUEST['distrib'] == 'False': distrib = False self.page_context['init_code'] += 'toggleTminus1vis();' except: pass self.page_context['distrib'] = str(distrib) footprint = False try: if request.REQUEST['footprint'] == 'True': footprint = True self.page_context['init_code'] += 'footprintvisibility();' except: pass self.page_context['footprint'] = str(footprint) markers = False try: if request.REQUEST['markers'] == 'True': markers = True self.page_context['init_code'] += 'graph.markForDeletion();' except: pass self.page_context['markers'] = str(markers) shock = False try: if request.REQUEST['shock'] == 'True': shock = True self.page_context['init_code'] += 'remove_onclick();' except: pass self.page_context['shock'] = str(shock) displayiteration = 'final' try: if request.REQUEST['iter'] == 'start': displayiteration = 'start' except: pass self.page_context['iter'] = displayiteration api = request.GET.get('api') if api is None or api == '' or api == 'leaflet': api = 'leaflet' else: api = 'OL' self.page_context['api'] = api stage = 1 try: if request.REQUEST['stage']: stage = int(request.REQUEST['stage']) except: pass self.page_context['stage'] = stage page_subtitle = 'unknown' # process what gets displayed in the text box and the functions of the next and previous buttons if stage == 1: #prevbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=0&tab=map">« previous</a>' prevbutton = '' nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=2&tab=topo&distrib=True">next »</a>' starttext = 'This is the supply chain of a fictional electronics company <i>Pomegranate</i> which is manufacturing and distributing a 4G tablet computer. The map is interactive: hold your cursor over a node to see its data. Use the top buttons to isolate different parts of the network - the Distribution network of completed products to their markets, and Suppliers in Tier 1 (assembly of principle components); Tier 2 (sub-components); Tier 3 (raw materials). ' page_subtitle = '1. Supply Chain Geography of a Global Electronics Company' if stage == 2: prevbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=1&tab=map&distrib=True">« back</a>' nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=3&tab=map&footprint=True&distrib=True">next »</a>' starttext = 'Here we switch the view of the supply chain from geographical (plotted on a world map) to topological (a force-directed graph diagram of the network model). Note that the same data are retained - your cursor still brings up the same data in a pop-up. The force-directed graph can be dragged and manipulated to view interactivity of the network. Topology of a network shows process flow, choke points and dependencies.' page_subtitle = '2. Supply Chain Network Model' if stage == 3: prevbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=2&tab=topo&distrib=True">« back</a>' nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=4&tab=map&distrib=True&markers=True&footprint=True">next »</a>' starttext = 'Back on the geographical map, the supply chain process is now affected by a shock scenario from our <a href="/taxonomy">Threat Observatory</a>. In this example we show the footprint of an extreme cold winter event that might be expected about once a century, as documented in our <a href="/uploaded/documents/Freeze.pdf" target="_new">Freeze Threat Profile</a> working paper. Freezing conditions, with heavy snow and ice, are experienced for over 6 weeks.' page_subtitle = '3. Applying a Scenario Footprint' if stage == 4: prevbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=3&tab=map&footprint=True&distrib=True">« back</a>' nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=5&tab=topo&distrib=True&markers=True&footprint=True">next »</a>' starttext = 'The cold weather is so extreme it reduces manufacturing productivity, stops transport and suppresses consumer demand. A spatial query identifies the nodes of the network that lie within each intensity zone of the freeze event and assigns an intensity to each node. All of the nodes affected by the freeze event are highlighted by a blue diamond. ' page_subtitle = '4. Identifying the Affected Nodes' if stage == 5: prevbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=4&tab=map&distrib=True&markers=True&footprint=True">« back</a>' nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=6&tab=topo&distrib=True&markers=True&footprint=True&shock=True">next »</a>' starttext = 'The nodes that are affected by the freeze event are identified by their position in the supply chain network model. Their performance is degraded depending on the intensity of the scenario that they experienced. For simplicity in this example the node is assumed to be rendered completely inactive.' page_subtitle = '5. Affected Nodes in the Supply Chain Model' if stage == 6: prevbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=5&tab=topo&distrib=True&markers=True&footprint=True">« back</a>' nextbutton = '<a href="/page/26">next »</a>' starttext = 'The nodes are disabled in the network. In graph theory it performs a k-cut operation where k=41, with an identity of co-location in the freeze footprint. Links to and from an inactive node are severed. The network functionality is extremely compromised. The network re-resolves but with extremely limited residual value function. A number of nodes are completely disconnected.' page_subtitle = '6. Shock the System' self.page_context['nextbutton'] = nextbutton self.page_context['prevbutton'] = prevbutton self.page_context['starttext'] = starttext n = Network() status = n.load(6) #load a network from the asset engine database by its network id if not status: return self.showErrorPage(request, 'Error loading network : ' + n.statusMessage) # process the graph to set up the special attributes that are going to be sent to the client side javascript via JSON for node in n.layergraphs[0].nodes(data=True): # when data=True we get the attributes of the node that we must unpack from an array guid = node[0] attributes = node[1] # the node name attribute is used to form the pop up html attributes['name'] = '<div class="n">Node ' + attributes['guid'] + '</div><div class="t">Tier ' + str(attributes['tier']) + '</div><div class="a">' + attributes['activity'] + '</div><div class="p">' + attributes['name'] + '</div><div class="c">' + attributes['countrycode'] + '</div>' # append the in/out edge count to the node name attributes['name'] += '<div class="e">Edges in: ' + unicode(n.layergraphs[0].in_degree(guid)) + ' out: ' + unicode(n.layergraphs[0].out_degree(guid)) + '</div>' #get the tier of this node tier = attributes['tier'] # find the edges that go out of this node out_edges = n.layergraphs[0].out_edges(guid) # gets outward edges for edge in out_edges: # create a tier attribute on the edge n.layergraphs[0][edge[0]][edge[1]]['tier']=tier for edge in n.layergraphs[0].edges(data=True): n.layergraphs[0][edge[0]][edge[1]]['value'] = 1 # d3 needs this # get some overall network metrics undirectedG = n.layergraphs[0].to_undirected() self.page_context['diameter'] = nx.diameter(undirectedG) self.page_context['radius'] = nx.radius(undirectedG) self.page_context['average_clustering'] = round(nx.average_clustering(undirectedG),3) self.page_context['transitivity'] = round(nx.transitivity(undirectedG),3) self.page_context['number_connected_components'] = nx.number_connected_components(undirectedG) import operator betweenness_centrality = nx.betweenness_centrality(n.layergraphs[0]) self.page_context['betweenness_centrality'] = sorted(betweenness_centrality.iteritems(),key=operator.itemgetter(1),reverse=True)[0][0][5:] # find node with largest betweenness centrality H = nx.connected_component_subgraphs(undirectedG)[0] # largest connected component self.page_context['number_of_nodes'] = len(H.nodes()) # apply freeze footprint, assigning intensities to nodes in footprint from footprints.footprint import Footprint f = Footprint('freeze100', ['intensity']) f.apply('asset_engine.node', n.layergraphs[0]) jsonGraphStr = n.get_json() # now we have the json string which has intensities for the footprint, # apply freeze footprint again but this time delete the nodes in the footprint f.apply('asset_engine.node', n.layergraphs[0], None, True) # get same overall network metrics now we have the post K-cut network undirectedG = n.layergraphs[0].to_undirected() self.page_context['average_clustering_K'] = round(nx.average_clustering(undirectedG),3) self.page_context['transitivity_K'] = round(nx.transitivity(undirectedG),3) self.page_context['number_connected_components_K'] = nx.number_connected_components(undirectedG) betweenness_centrality = nx.betweenness_centrality(n.layergraphs[0]) self.page_context['betweenness_centrality_K'] = sorted(betweenness_centrality.iteritems(),key=operator.itemgetter(1),reverse=True)[0][0][5:] # find node with largest betweenness centrality H = nx.connected_component_subgraphs(undirectedG)[0] # largest connected component self.page_context['number_of_nodes_K'] = len(H.nodes()) # load a network from its GEXF file # base bank network #n.importGexf('c:\\inetpub\\wwwroot\\pydev\\systemshock\\modellingengine\\fincat\\parameters\\countries.gexf') # initial capital ratio #n.importGexf('c:\\inetpub\\wwwroot\\pydev\\systemshock\\modellingengine\\fincat\\parameters\\initial.gexf') # final capital ratio #n.importGexf('c:\\inetpub\\wwwroot\\pydev\\systemshock\\modellingengine\\fincat\\parameters\\results.gexf') #jsonGraphStr = n._get_json() session_key = '' if request.session._session_key is None: request.session._get_or_create_session_key() # note this returns the wrong key, so can't use the key until the page's next roundtrip else: session_key = request.session._session_key #if session_key != '': # n.exportGexf('c:\\inetpub\\wwwroot\\networksessions\\' + session_key + '.gexf') current_object = Page.objects.get(pk=ix) page_title = current_object.name #page_subtitle = current_object.subtitle self.page_context['ix'] = ix self.page_context['page_title'] = page_title self.page_context['page_subtitle'] = page_subtitle # display pageFormDisplay = PageFormDisplay (instance=current_object) pagefields = self.createFormFieldStructure( pageFormDisplay, current_object ) # using a class dictionary from Pagebase in weblib self.page_context['pageclass'] = 'networkmanager' self.page_context['tablesetup1'] = pagefields self.page_context['editlink'] = '/laptopsupplychain' self.page_context['current_object'] = current_object self.page_context['this_page'] = request.path self.page_context['jsonGraph'] = jsonGraphStr self.page_context['api'] = api #self.page_context['haiti'] = jsonStr ############### # POST ############### if request.method == 'POST': pageFormEdit = PageFormEdit(request.POST, instance=current_object , prefix='mainpageform') # A form bound to the POST data, prefix allows multiple forms if pageFormEdit.is_valid(): # All validation rules pass current_object.lastupdate = datetime.now() current_object.lastupdatebyid = request.user.id pageFormEdit.save() return HttpResponseRedirect('/laptopsupplychain') # Redirect after successful POST to the non editing version else: self.page_context['form'] = pageFormEdit return render(request, self.template_name, self.page_context) # Error - return just the form when there is an error - the template must not try and render anything outside the form because the contact data is not present ############### # GET ############### if request.method == 'GET': # edit form if self.page_context['editmode']: pageFormEdit = PageFormEdit (instance=current_object, prefix="mainpageform") #prefix allows multiple forms self.page_context['form'] = pageFormEdit return render(request, self.template_name, self.page_context)