def dispatch(self, request, *args, **kwargs):

        if self.preProcessPage(request, **kwargs):

            # create a structure that will be sent to the web page graph viewer
            geonetworkviewerstructure = {}
            geonetworkviewerstructure["startup"] = {}

            # create a structure that will be sent to the web page map viewer
            mapviewerstructure = {}
            mapviewerstructure["startup"] = {}

            tabmode = "map"
            try:
                if request.REQUEST["tab"] == "topo":
                    tabmode = "topo"
            except:
                pass
            geonetworkviewerstructure["startup"]["tabmode"] = str(tabmode).lower

            footprint = False
            try:
                if request.REQUEST["footprint"] == "True":
                    footprint = True
            except:
                pass
            geonetworkviewerstructure["startup"]["footprint"] = footprint
            mapviewerstructure["startup"]["footprint"] = footprint

            markers = False
            try:
                if request.REQUEST["markers"] == "True":
                    markers = True
            except:
                pass
            geonetworkviewerstructure["startup"]["markers"] = markers
            mapviewerstructure["startup"]["markers"] = markers

            shock = False
            try:
                if request.REQUEST["shock"] == "True":
                    shock = True
            except:
                pass
            geonetworkviewerstructure["startup"]["shock"] = shock
            mapviewerstructure["startup"]["shock"] = shock

            n = Network()
            try:
                ix = int(self.page_context["ix"])
            except:
                return self.showErrorPage(request, "Invalid network id")

            status = n.load(ix)  # load a network from the asset engine database by its network id

            if not status:
                return self.showErrorPage(request, "Error loading network : " + n.statusMessage)

            # make default popup
            n.makePopup()

            # create the list of nodes - may be more than one list depending on how many networks
            self.page_context["nodelistlist"] = []
            listganglist = ["graph1", "map2"]
            listviewerid = 1

            for index, graphmodels in enumerate(n.graphmodelslist):
                node_filter = n.layers[index].layerid.nodefilter
                nodequeryset = (
                    graphmodels.Nodes.objects.only("id", "guid", "image1", "name", "countrycode").all().order_by("name")
                )
                if node_filter is not None:
                    nodequeryset = nodequeryset.filter(**ast.literal_eval(node_filter))
                fieldlist = [
                    [
                        {"guid": {"title": "GUID", "type": "text"}}
                    ],  # NB guid must be first for the ganged grid list templatetag to find it
                    [{"image1": {"title": "Image", "type": "WebLibPhoto", "photosize": "admin_thumbnail"}}],
                    [{"name": {"title": "Node name", "type": "text"}}],
                    [{"countrycode": {"title": "Country", "type": "text"}}],
                ]
                fieldstructure = {
                    "entity": nodequeryset,
                    "targeturl": "/node/" + unicode(n.layeridlist[index]) + "/",
                    "fields": fieldlist,
                    "params": {"linkforeignkeys": False, "ganglist": listganglist, "viewerid": listviewerid},
                }
                self.page_context["nodelistlist"].append(fieldstructure)

            # set up the scenario
            freezescenario = Freeze()
            viewer = Viewer()

            if self.page_context["ix"] == "6":
                # run Ben's supply chain model
                supplychainmodel = SupplyChain(freezescenario)
                supplychainmodel.run_model(n, 0, 0, shock)
                # n.exportGexf('c:\\inetpub\\wwwroot\\networksessions\\pomegranite2.gexf')
                supplychainmodel.get_results()
                geonetworkviewerstructure["jsonGraph"] = supplychainmodel.json
                mapviewerstructure["geojson"] = supplychainmodel.geojson

            else:
                # simple viewer only
                viewermodel = ModellingBase(viewer)
                viewermodel.run_model(n)
                viewermodel.get_results()
                geonetworkviewerstructure["jsonGraph"] = viewermodel.json
                mapviewerstructure["geojson"] = viewermodel.geojson

            # run freeze model over supply chain - applies footprint and passes output in the JSON
            # supplychainmodel = SupplyChain(freezescenario)
            # supplychainmodel.get_run(self.page_context['ix'])
            # supplychainmodel.run_model(n)
            # supplychainmodel.get_results()
            # geonetworkviewerstructure['jsonGraph'] = supplychainmodel.json

            # get network metrics - by default for the first layer in the network if multiple layers
            geonetworkviewerstructure["metrics"] = n.getMetrics()

            current_object = n.networkobject
            page_title = current_object.name
            page_subtitle = current_object.description
            self.page_context["page_title"] = page_title
            self.page_context["page_subtitle"] = page_subtitle

            # display network fields and editable form
            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"] = "/networkmanager"
            self.page_context["current_object"] = current_object
            self.page_context["this_page"] = request.path

            # pass the data to the network viewer template tag
            geonetworkviewerstructure["ganglist"] = ["map2"]  # connects graph viewer to map viewer
            geonetworkviewerstructure["uniqueid"] = 1  # allows multiple viewers on same page
            self.page_context["graphviewer1"] = geonetworkviewerstructure

            # pass the data to the map viewer template tag
            mapviewerstructure["ganglist"] = ["graph1"]  # connects map viewer to graph viewer
            mapviewerstructure["uniqueid"] = 2  # allows multiple viewers on same page
            self.page_context["mapviewer2"] = mapviewerstructure

            ###############
            # 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(
                        "/networkmanager"
                    )  # 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)
    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">&laquo; previous</a>'
                prevbutton = ''
                nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=2&tab=topo&distrib=True">next &raquo;</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">&laquo; back</a>'
                nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=3&tab=map&footprint=True&distrib=True">next &raquo;</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">&laquo; back</a>'
                nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=4&tab=map&distrib=True&markers=True&footprint=True">next &raquo;</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">&laquo; back</a>'
                nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=5&tab=topo&distrib=True&markers=True&footprint=True">next &raquo;</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">&laquo; back</a>'
                nextbutton = '<a href="/laptopsupplychain/' + self.page_context['ix'] + '?stage=6&tab=topo&distrib=True&markers=True&footprint=True&shock=True">next &raquo;</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">&laquo; back</a>'
                nextbutton = '<a href="/page/26">next &raquo;</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)
Example #3
0
    def dispatch(self, request, *args, **kwargs):

        if self.preProcessPage(request, **kwargs):

            # create a structure that will be sent to the web page graph/map viewer
            geonetworkviewerstructure = {}
            geonetworkviewerstructure['startup'] = {}

            tabmode = 'list'
            viewertabmode = 'list'
            self.page_context['init_code'] = ''
            try:
                if request.REQUEST['tab'] == 'map':
                    tabmode = 'map'
                    viewertabmode = 'map'
                if request.REQUEST['tab'] == 'list':
                    tabmode = 'list'
                    viewertabmode = 'list'
                if request.REQUEST['tab'] == 'topo':
                    tabmode = 'map'
                    viewertabmode = 'topo'
                    self.page_context['init_code'] = 'toggle();'
            except:
                pass
            self.page_context['tabmode'] = tabmode
            geonetworkviewerstructure['startup']['tabmode'] = str(viewertabmode).lower

            displayiteration = 'final'
            iteration = 1
            try:
                if request.REQUEST['iter'] == 'start':
                    displayiteration = 'start'
                    iteration = 0
            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 = 0
            try:
                if request.REQUEST['stage']:
                    stage = int(request.REQUEST['stage'])
            except:
                pass
            self.page_context['stage'] = stage

            # process what gets displayed in the text box and the functions of the next and previous buttons
            page_subtitle = 'unknown'
            nextbutton = ''
            prevbutton = ''
            starttext = ''

            if stage == 0:
                prevbutton = ''
                nextbutton = '<a href="/fincatrun/' + self.page_context['ix'] + '?stage=1&tab=topo&iter=start">next &raquo;</a>'
                starttext = 'Basic diagnostic information for the last run of the model. To page through the model&#39;s outputs in map and topological forms click on <b>next</b>'
                page_subtitle = 'Model Status Display'

            if stage == 1:
                prevbutton = ''
                nextbutton = '<a href="/fincatrun/' + self.page_context['ix'] + '?stage=2&tab=map&iter=start">next &raquo;</a>'
                starttext = 'The world&#39;s financial system can be represented by a &#39;Core Periphery&#39; network model. This interactive model shows a simplified representation with each country represented by a single node, based on data from the IMF. Your cursor will show data about each country&#39;s banking system, regulatory regions and capital ratio at the start of the model run. This draggable, force-directed graph shows the dark green core banks, serving many light green periphery banking systems. '
                page_subtitle = '1. The Global Banking Network'

            if stage == 2:
                prevbutton = '<a href="/fincatrun/' + self.page_context['ix'] + '?stage=1&tab=topo&iter=start">&laquo; previous</a>'
                nextbutton = '<a href="/page/28">next &raquo;</a>'
                starttext = 'The banking network can be seen geographically. This screen shows the initial conditions of the model with the global banking network shown on a world map. Each central bank is shown in its capital city. "Core" banks are shown darker green. Mouse over each bank to get more details.  '
                page_subtitle = '2. The Geography of Banking'

            if stage == 6:
                prevbutton = '<a href="/page/27">&laquo; previous</a>'
                nextbutton = '<a href="/fincatrun/' + self.page_context['ix'] + '?stage=7&tab=topo&iter=final">next &raquo;</a>'
                starttext = 'This screen shows a subset of the iterations of the model. Key central banks are shown with their balance sheets taken at iteration points in the model as they change.'
                page_subtitle = '6. Model Run Progression'

            if stage == 7:
                prevbutton = '<a href="/fincatrun/' + self.page_context['ix'] + '?stage=6&tab=list">&laquo; previous</a>'
                nextbutton = '<a href="/fincatrun/' + self.page_context['ix'] + '?stage=8&tab=map&iter=final">next &raquo;</a>'
                starttext = 'The banking network at the end of the model run shows the capital ratios of the banks that are worst affected, from green to red, with red being worst. The model provides a lot of detailed data of the crisis progression for analysis.'
                page_subtitle = '7. Contagion Mapping'

            if stage == 8:
                prevbutton = '<a href="/fincatrun/' + self.page_context['ix'] + '?stage=7&tab=topo&iter=final">&laquo; previous</a>'
                nextbutton = '<a href="/page/21">next &raquo;</a>'
                starttext = 'The crisis in the international banking network can be seen geographically. The contagion has spread from its initial starting point and has impacted many countries throughout Europe and has affected countries further afield.'
                page_subtitle = '8. The Geography of the Financial Crisis'

            self.page_context['nextbutton'] = nextbutton
            self.page_context['prevbutton'] = prevbutton
            self.page_context['starttext'] = starttext

            self.page_context['results'] = {'entity': [], 'targeturl': '', 'fields': [] }

            current_object = None

            if not self.page_context['addmode']:  # we are reading an existing record
                try:
                    current_object = FinCatRun.objects.get(pk=self.page_context['ix'])
                except ObjectDoesNotExist:
                    return self.showErrorPage(request, 'Error: Record ' + str(self.page_context['ix']) + ' does not exist')
                except:
                    return self.showErrorPage(request, 'Error: invalid parameter supplied')

                self.page_context['current_object'] = current_object
                self.page_context['page_title'] = current_object.name
                #page_subtitle = current_object.name
                self.page_context['page_subtitle'] = page_subtitle

                # get the picked results data structure from the last run of this model instance
                if not self.page_context['editmode'] and current_object.results is not None and current_object.results != '':
                    results = cPickle.loads(base64.b64decode(current_object.results))

                    balanceSheets = results[0][0]   # when bankId lending investments cash borrowing deposits capital
                    borrowings = results[0][1]      # when fromBankId toBankId amount
                    defaults = results[0][2]        # when bankId ratio
                    holdings = results[1][0]        # when investmentId bankId amount
                    prices = results[1][0]          # when investmentId price

                    # results table

                    fieldlist = \
                        [
                            [{'bankId':  {'title': 'Bank id', 'type': 'CharField', }}],
                            [{'when':  {'title': 'Iteration', 'type': 'IntegerField', }}],
                            [{'lending':  {'title': 'Lending', 'type': 'DecimalField', 'decimal_places': 1, }}],
                            [{'investments':  {'title': 'Investments', 'type': 'DecimalField', 'decimal_places': 1, }}],
                            [{'cash':  {'title': 'Cash', 'type': 'DecimalField', 'decimal_places': 1, }}],
                            [{'borrowing':  {'title': 'Borrowing', 'type': 'DecimalField', 'decimal_places': 1, }}],
                            [{'deposits':  {'title': 'Deposits', 'type': 'DecimalField', 'decimal_places': 1, }}],
                            [{'capital':  {'title': 'Capital', 'type': 'DecimalField', 'decimal_places': 1, }}],
                            [{'capitalratio':  {'title': 'Capital ratio %', 'type': 'DecimalField', 'decimal_places': 1, }}],
                        ]

                    balanceSheets2 = [balanceSheet for balanceSheet in balanceSheets if balanceSheet.bankId in ['Japan', 'United Kingdom', 'France', 'United States', 'Greece','Italy', 'Germany', 'China','Russia','Spain']]
                    from operator import itemgetter, attrgetter
                    balanceSheets3 = sorted(balanceSheets2, key=attrgetter('bankId'), reverse=False)

                    balanceSheet4 = []
                    for b in balanceSheets3:
                        # create a new named tuple type by adding a field to the balance sheet named tuple
                        newtupletype = namedtuple ('BalanceSheet', b._fields+('capitalratio',))
                        # copy values across
                        d = newtupletype(b.when,b.bankId,b.lending,b.investments,b.cash,b.borrowing,b.deposits,b.capital,(b.capital/(b.lending+b.investments+b.cash))*100)
                        balanceSheet4.append(d)

                    resultsFields = {'entity': balanceSheet4, 'targeturl': '/bank/', 'fields': fieldlist }
                    self.page_context['results'] = resultsFields

                    n = Network()
                    #try:
                    #    ix = int(self.page_context['ix'])
                    #except:
                    #    return self.showErrorPage(request, 'Invalid network id')

                    status = n.load(7)  # load a network from the asset engine database by its network id

                    if not status:
                        return self.showErrorPage(request, 'Error loading network : ' + n.statusMessage)

                    # make default popup
                    n.makePopup()

                    # get network metrics
                    geonetworkviewerstructure['metrics'] = n.getMetrics()

                    # iterate the banks in the network
                    for node in n.layergraphs[0].nodes(data=True):

                        nodeid = node[0] #node array index 0 is the node id, index 1 is the attribute list
                        attributes = node[1]
                        attributes['intensity'] = 0
                        attributes['guid'] = nodeid

                        count = n.layergraphs[0].in_degree(nodeid)

                        # if the tier is not already defined in the file, define it
                        if 'tier' not in attributes:

                            # base tier on number of incoming edges
                            tier = 3
                            if count > 8:
                                tier = 2
                            if count > 15:
                                tier = 1
                            if attributes['core'] == 'True':
                                tier = 0

                        else:
                            tier = attributes['tier']

                        in_edges = n.layergraphs[0].in_edges(nodeid)  # gets inward edges
                        for edge in in_edges:
                            # create a tier attribute on the edge
                            n.layergraphs[0][edge[0]][edge[1]]['tier']=tier
                            n.layergraphs[0][edge[0]][edge[1]]['linkstyle'] = 0

                        attributes['tier'] = tier
                        attributes['popup'] = '<div class="n">' + attributes['region'] + '</div><div class="a">' + attributes['label'] + '</div><div>Outward links:' + unicode(n.layergraphs[0].out_degree(nodeid)) + '</div><div>Inward links:' + unicode(n.layergraphs[0].in_degree(nodeid)) + '</div>'

                        bankId = attributes['label']
                        # each bank has several balance sheet records taken as the model runs
                        allBSRecords = [balanceSheet for balanceSheet in balanceSheets if balanceSheet.bankId in [bankId]]
                        # initial balance sheet record
                        initBSRecord = allBSRecords[0]
                        # the last balance sheet record is the final result
                        finalBSRecord = allBSRecords[-1]
                        # compute capital ratio
                        initcapratio = (initBSRecord.capital/(initBSRecord.lending+initBSRecord.investments+initBSRecord.cash))*100
                        finalcapratio = (finalBSRecord.capital/(finalBSRecord.lending+finalBSRecord.investments+finalBSRecord.cash))*100
                        # store as an attribute on the bank node
                        attributes['initcapratio'] = round(initcapratio, 1)
                        attributes['finalcapratio'] = round(finalcapratio, 1)

                        tier = 3 # banks in good shape - capratio > 5.5

                        # core banks in good shape
                        if attributes['core'] == 'True':
                                tier = 4

                        if finalcapratio < 0.02:
                            tier = 0
                        else:
                            if finalcapratio < 2.0:
                                tier = 1
                            else:
                                if finalcapratio < 4.0:
                                    tier = 2
                                else:
                                    if finalcapratio < 5.5:
                                        tier = 3

                         # if an iter querystring parameter was set to 'start' then
                         # color up nodes by whether they are core or not
                        if displayiteration == 'start':
                            tier = 3

                            if attributes['core'] == 'True':
                                tier = 4

                        attributes['tier'] = tier
                        attributes['nodestyle'] = tier

                        # add the cap ratio to the popup
                        if displayiteration == 'start':
                            attributes['popup'] = attributes['popup'] + '<br/>Init cap ratio ' + unicode(round(initcapratio, 1)) + '%'
                        else:
                            attributes['popup'] = attributes['popup'] + '<br/>Final cap ratio ' + unicode(round(finalcapratio, 1)) + '%'

                        # add in if its core
                        if attributes['core'] == 'True':
                            attributes['popup'] = attributes['popup'] + '<br/>Core'

                    # to reduce the size of the JSON string, we delete the node attributes we dont need,
                    #n.minimise()

                    #jsonGraphStr = n.get_json()
                    #self.page_context['jsonGraph'] = jsonGraphStr

                    bankdefault = BankDefault(['Greece', 'Cyprus'])  # get scenario
                    liquiditymodel = Liquidity(bankdefault)
                    liquiditymodel.get_run(self.page_context['ix']) # load previous model run from database
                    activelayer = 0
                    liquiditymodel.run_model(n, activelayer, iteration)  # TODO we actually need to run the model in the POST, not here
                    liquiditymodel.get_results(True, activelayer, iteration)
                    geonetworkviewerstructure['jsonGraph'] = liquiditymodel.json


            # other info to pass through the page context
            self.page_context['pageclass'] = 'fincatrun'
            self.page_context['editlink'] = ('/' + 'fincatrun' + '/' + str(self.page_context['ix'])).lower()

            # pass the data to the geonetwork viewer template tag
            geonetworkviewerstructure['uniqueid'] = 1  # allows multiple viewers on same page
            self.page_context['geonetworkviewer1'] = geonetworkviewerstructure


            ###############
            # POST
            ###############

            if request.method == 'POST':

                if self.page_context['addmode']:  # new record, create at first with default values
                    current_object = FinCatRun()
                    current_object.name = 'untitled'
                    #current_object.networkid = Network.objects.get(pk=1)
                    current_object.lastupdate = datetime.now()
                    current_object.lastupdatebyid = request.user.id
                    current_object.ownerid = request.user.id
                    current_object.status = 'not run yet, or run failed'
                    self.page_context['editmode'] = True  # in case it turns out there is an error in input

                # read the page form
                # note as we upload a file here, we need enctype="multipart/form-data" in the <form> tag and to add request.FILES, to the call below
                pageFormEdit = PageFormEdit(request.POST, request.FILES, instance=current_object , prefix='mainpageform') # A form bound to the POST data, prefix allows multiple forms

                if pageFormEdit.is_valid():  # All validation rules pass

                    self.page_context['editmode'] = False # no errors

                    # now create the record in the database
                    current_object.save()

                    # now we know the new record's id
                    self.page_context['ix'] = current_object.id
                    self.page_context['current_object'] = current_object

                    # now save the screen form values into the database
                    pageFormEdit.save()

                    # see if a parameter file got uploaded
                    if current_object.parameterfile.name != '':
                        # process a new parameter file here into the fincat_bankparameters table
                        # first erase all pre-existing records, if any, with runid equal to this one

                        # after a successful upload of the parameter file, we need to delete it from the record so it does not get reuploaded every time
                        # but we save its name in a separate field
                        current_object.originalparameterfilename = unicode(request.FILES['mainpageform-parameterfile'])
                        current_object.actualparameterfilename = current_object.parameterfile.name
                        current_object.lastparameterfileuploaddate = datetime.now()
                        current_object.parameterfile = None

                    # run the model
                    pList, basicGraph = utils.read_params_file(PATH, 'countries1.xml')
                    results = simulator.setup_simulation(pList, basicGraph)

                    current_object.rundate = datetime.now()
                    current_object.status = 'Success'
                    current_object.results = base64.b64encode(cPickle.dumps(results, cPickle.HIGHEST_PROTOCOL))
                    current_object.save()

                    return HttpResponseRedirect('/fincatrun/' + str(self.page_context['ix'])) # 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':

                if self.page_context['addmode']:  # new record - initialise a dummy record that we dont save with defaults to see on the page
                    current_object = FinCatRun()
                    current_object.name = 'untitled'
                    #current_object.networkid = Network.objects.get(pk=1)
                    self.page_context['editmode'] = True

                if self.page_context['editmode']:  # edit or add mode
                    current_object.status = 'Pending run...'
                    pageFormEdit = PageFormEdit(instance=current_object, prefix="mainpageform") # prefix allows multiple forms
                    self.page_context['form'] = pageFormEdit
                else:
                    pageFormDisplay = PageFormDisplay (instance=current_object) # display mode
                    pagefields = self.createFormFieldStructure( pageFormDisplay, current_object )
                    self.page_context['tablesetup1'] = pagefields  # pass field structure to generictablerenderer

                return render(request, self.template_name, self.page_context)
Example #4
0
    def dispatch(self, request, *args, **kwargs):

        if self.preProcessPage(request, **kwargs):

            # create a structure that will be sent to the web page graph/map viewer
            geonetworkviewerstructure = {}
            geonetworkviewerstructure['startup'] = {}

            tabmode = 'map'
            try:
                if request.REQUEST['tab'] == 'topo':
                    tabmode = 'topo'
            except:
                pass
            geonetworkviewerstructure['startup']['tabmode'] = str(tabmode).lower

            footprint = False
            try:
                if request.REQUEST['footprint'] == 'True':
                    footprint = True
            except:
                pass
            geonetworkviewerstructure['startup']['footprint'] = footprint

            markers = False
            try:
                if request.REQUEST['markers'] == 'True':
                    markers = True
            except:
                pass
            geonetworkviewerstructure['startup']['markers'] = markers

            shock = False
            try:
                if request.REQUEST['shock'] == 'True':
                    shock = True
            except:
                pass
            geonetworkviewerstructure['startup']['shock'] = shock

            n = Network()
            try:
                ix = int(self.page_context['ix'])
            except:
                return self.showErrorPage(request, 'Invalid network id')

            status = n.load(ix)  # load a network from the asset engine database by its network id

            if not status:
                return self.showErrorPage(request, 'Error loading network : ' + n.statusMessage)

            # make default popup
            n.makePopup()

            # get network metrics - by default for the first layer in the network if multiple layers
            geonetworkviewerstructure['metrics'] = n.getMetrics()

            freezescenario = Freeze()
            viewer = Viewer()

            if self.page_context['ix'] == '6':
                # run Ben's supply chain model
                supplychainmodel = SupplyChain(None)
                supplychainmodel.run_model(n)
                #n.exportGexf('c:\\inetpub\\wwwroot\\networksessions\\pomegranite2.gexf')
                supplychainmodel.get_results()
                geonetworkviewerstructure['jsonGraph'] = supplychainmodel.json
            else:
                # simple viewer only
                viewermodel = ModellingBase(viewer)
                viewermodel.run_model(n)
                viewermodel.get_results()
                geonetworkviewerstructure['jsonGraph'] = viewermodel.json

            # run freeze model over supply chain - applies footprint and passes output in the JSON
            #supplychainmodel = SupplyChain(freezescenario)
            #supplychainmodel.get_run(self.page_context['ix'])
            #supplychainmodel.run_model(n)
            #supplychainmodel.get_results()
            #geonetworkviewerstructure['jsonGraph'] = supplychainmodel.json



            current_object = n.networkobject
            page_title = current_object.name
            page_subtitle = current_object.description
            self.page_context['page_title'] = page_title
            self.page_context['page_subtitle'] = page_subtitle

            # display network fields and editable form
            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'] = '/networkmanager'
            self.page_context['current_object'] = current_object
            self.page_context['this_page'] = request.path

            # pass the data to the geonetwork viewer template tag
            geonetworkviewerstructure['uniqueid'] = 1  # allows multiple viewers on same page
            self.page_context['geonetworkviewer1'] = geonetworkviewerstructure


            ###############
            # 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('/networkmanager') # 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)