[cig-commits] r11778 - in cs/portal/trunk/seismo/SeismoWebPortal: . templates/SeismoWebPortal

leif at geodynamics.org leif at geodynamics.org
Tue Apr 8 18:06:43 PDT 2008


Author: leif
Date: 2008-04-08 18:06:43 -0700 (Tue, 08 Apr 2008)
New Revision: 11778

Modified:
   cs/portal/trunk/seismo/SeismoWebPortal/cmt.py
   cs/portal/trunk/seismo/SeismoWebPortal/models.py
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineos_parameters.pml
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/run_list.py
   cs/portal/trunk/seismo/SeismoWebPortal/views.py
Log:
Dusted-off the daemon's server-side HTTP interface: Runs, Jobs,
OutputFiles, and input file downloads.


Modified: cs/portal/trunk/seismo/SeismoWebPortal/cmt.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/cmt.py	2008-04-09 00:35:29 UTC (rev 11777)
+++ cs/portal/trunk/seismo/SeismoWebPortal/cmt.py	2008-04-09 01:06:43 UTC (rev 11778)
@@ -4,7 +4,7 @@
 
     def __init__(self):
 
-        self.dataSource = ''
+        self.dataSource = "ZZZ"
         self.year = 0000
         self.month = 00
         self.day = 00
@@ -16,9 +16,9 @@
         self.sourceDepth = 0.0
         self.sourceMB = 0.0
         self.sourceMs = 0.0
-        self.regionName = ""
+        self.regionName = "ZZZZ"
         
-        self.eventName = ''
+        self.eventName = "000000Z"
         self.timeShift = 0.0
         self.halfDuration = 0.0
         self.latitude = 0.0
@@ -32,37 +32,52 @@
         self.Mtp = 0.0
 
 
+    @classmethod
     def createFromDBModel(cls, model):
         cmtSolution = CMTSolution()
-        cmtSolution.dataSource = model.event.dataSource.name
-        cmtSolution.year = model.event.when.year
-        cmtSolution.month = model.event.when.month
-        cmtSolution.day = model.event.when.day
-        cmtSolution.hour = model.event.when.hour
-        cmtSolution.minute = model.event.when.minute
-        cmtSolution._second = float(model.event.when.second) + (float(model.event.microsecond) / 1000000.0)
-        cmtSolution.sourceLatitude = model.event.sourceLatitude
-        cmtSolution.sourceLongitude = model.event.sourceLongitude
-        cmtSolution.sourceDepth = model.event.sourceDepth
-        cmtSolution.sourceMB = model.event.sourceMB
-        cmtSolution.sourceMs = model.event.sourceMs
-        cmtSolution.regionName = model.event.region.name
-        cmtSolution.eventName = model.eventName
-        cmtSolution.timeShift = model.timeShift
-        cmtSolution.halfDuration = model.halfDuration
-        cmtSolution.latitude = model.latitude
-        cmtSolution.longitude = model.longitude
-        cmtSolution.depth = model.depth
-        cmtSolution.Mrr = model.Mrr
-        cmtSolution.Mtt = model.Mtt
-        cmtSolution.Mpp = model.Mpp
-        cmtSolution.Mrt = model.Mrt
-        cmtSolution.Mrp = model.Mrp
-        cmtSolution.Mtp = model.Mtp
+        cmtSolution.initFromEventModel(model.event)
+        cmtSolution.initFromSourceModel(model)
         return cmtSolution
-    createFromDBModel = classmethod(createFromDBModel)
 
 
+    def initFromEventModel(self, model):
+        self.dataSource = model.dataSource.name
+        self.year = model.when.year
+        self.month = model.when.month
+        self.day = model.when.day
+        self.hour = model.when.hour
+        self.minute = model.when.minute
+        self._second = float(model.when.second) + (float(model.microsecond) / 1000000.0)
+        self.sourceLatitude = model.sourceLatitude
+        self.sourceLongitude = model.sourceLongitude
+        self.sourceDepth = model.sourceDepth
+        self.sourceMB = model.sourceMB
+        self.sourceMs = model.sourceMs
+        self.regionName = model.region.name
+        return self
+
+
+    def initFromSourceModel(self, model):
+        self.eventName = model.eventName
+        self.timeShift = model.timeShift
+        self.initFromCMTSolutionModel(model)
+        return self
+
+        
+    def initFromCMTSolutionModel(self, model):
+        self.halfDuration = model.halfDuration
+        self.latitude = model.latitude
+        self.longitude = model.longitude
+        self.depth = model.depth
+        self.Mrr = model.Mrr
+        self.Mtt = model.Mtt
+        self.Mpp = model.Mpp
+        self.Mrt = model.Mrt
+        self.Mrp = model.Mrp
+        self.Mtp = model.Mtp
+        return self
+
+
     def parse(cls, data):
         cmtList = []
         cmtSolution = None

Modified: cs/portal/trunk/seismo/SeismoWebPortal/models.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/models.py	2008-04-09 00:35:29 UTC (rev 11777)
+++ cs/portal/trunk/seismo/SeismoWebPortal/models.py	2008-04-09 01:06:43 UTC (rev 11778)
@@ -115,6 +115,12 @@
         return self.id
 
     @classmethod
+    def objectFromSnapshot(cls, snapshot):
+        if snapshot is None:
+            return None
+        return cls.objects.get(id = snapshot)
+
+    @classmethod
     def getLocation(cls, latitude, longitude):
         obj, created = cls.objects.get_or_create(latitude=latitude, longitude=longitude)
         return obj
@@ -183,6 +189,9 @@
     Mrp = models.FloatField(max_digits=19, decimal_places=10)
     Mtp = models.FloatField(max_digits=19, decimal_places=10)
 
+    latitude = property(lambda self: self.location.latitude)
+    longitude = property(lambda self: self.location.longitude)
+
     @classmethod
     def getCMTSolution(cls,
                        halfDuration, location, depth,
@@ -377,6 +386,11 @@
 NEX_C_CHOICES = oneThruNine
 
 
+class DummyBase(object):
+    def __init__(self, **kwds):
+        self.__dict__.update(kwds)
+
+
 class Specfem3DGlobeMesh(models.Model):
 
     fsNode = models.ForeignKey(FSNode, null=True)
@@ -440,6 +454,23 @@
             gamma_rotation_azimuth = self.gamma_rotation_azimuth,
             )
 
+    class Dummy(DummyBase):
+        def _getCenter(self, attr):
+            if self.location is None:
+                return 0.0
+            return getattr(self.location, attr)
+
+        center_latitude = property(lambda self: self._getCenter('latitude'))
+        center_longitude = property(lambda self: self._getCenter('longitude'))
+        def nex_xi(self): return 8 * self.nex_xi_c * self.nproc_xi
+        def nex_eta(self): return 8 * self.nex_eta_c * self.nproc_eta
+
+    @classmethod
+    def objectFromSnapshot(cls, snapshot):
+        snapshot['location'] = Location.objectFromSnapshot(snapshot['location'])
+        m = cls.Dummy(**snapshot)
+        return m
+
     class Admin:
         pass
 
@@ -485,6 +516,10 @@
             ellipticity = self.ellipticity,
             )
 
+    @classmethod
+    def objectFromSnapshot(cls, snapshot):
+        return cls(**snapshot)
+
     class Admin:
         pass
 
@@ -536,6 +571,21 @@
             zero_half_duration = workspace.zero_half_duration,
             )
 
+    class Dummy(DummyBase):
+        def auto_absorbing_conditions(self):
+            return not self.mesh.nchunks == 6
+
+    @classmethod
+    def objectFromSnapshot(cls, snapshot):
+        mesh = Specfem3DGlobeMesh.objectFromSnapshot(snapshot.pop('mesh'))
+        model = Specfem3DGlobeModel.objectFromSnapshot(snapshot.pop('model'))
+        zero_half_duration = snapshot.pop('zero_half_duration')
+        p = cls.Dummy(**snapshot)
+        p.mesh = mesh
+        p.model = model
+        p.zero_half_duration = zero_half_duration
+        return p
+    
     code = 1  # cf. CODE_CHOICES
     offering = "3D Synthetics by Specfem 3D Globe"
 
@@ -609,7 +659,11 @@
             max_depth = self.max_depth,
             )
 
+    @classmethod
+    def objectFromSnapshot(cls, snapshot):
+        return cls(**snapshot)
 
+
 class MineosModel(models.Model):
 
     fsNode = models.ForeignKey(FSNode, null=True)
@@ -635,7 +689,11 @@
         # models are immutable
         return self.id
 
+    @classmethod
+    def objectFromSnapshot(cls, snapshot):
+        return cls.objects.get(id = snapshot)
 
+
 class MineosParameters(models.Model):
 
     fsNode = models.ForeignKey(FSNode, null=True)
@@ -689,6 +747,20 @@
             step = self.step,
             )
 
+    class Dummy(DummyBase):
+        def nsamples(self):
+            from math import ceil
+            return int(ceil(self.record_length * 60.0 / self.step))
+
+    @classmethod
+    def objectFromSnapshot(cls, snapshot):
+        catalog = MineosModeCatalog.objectFromSnapshot(snapshot.pop('catalog'))
+        model = MineosModel.objectFromSnapshot(snapshot.pop('model'))
+        p = cls.Dummy(**snapshot)
+        p.catalog = catalog
+        p.model = model
+        return p
+    
     code = 2  # cf. CODE_CHOICES
     offering = "1D Synthetics by Mineos"
 
@@ -742,24 +814,6 @@
 
 
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Status
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-class Status(models.Model):
-    name = models.CharField(maxlength=100, primary_key=True)
-
-    @classmethod
-    def getStatus(cls, name):
-        status, created = cls.objects.get_or_create(name = name,
-                                                    defaults = dict(name = name))
-        return status
-
-    @classmethod
-    def statusNew(cls):     return cls.getStatus('new')
-
-
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # Requests
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -793,6 +847,14 @@
         return self._parameters
     parameters = property(lambda self: self._getParameters())
 
+    def _getRun(self):
+        if not hasattr(self, '_run'):
+            self._run = None
+            for run in self.run_set.all():
+                self._run = run
+        return self._run
+    run = property(_getRun)
+
     @classmethod
     def encodeParameters(cls, parameters):
         import base64
@@ -801,13 +863,6 @@
         return base64.encodestring(p)
 
 
-class Foo:
-    
-    def nsamples(self):
-        from math import ceil
-        return int(ceil(self.record_length * 60.0 / self.parameters.step))
-
-
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # Runs, Jobs
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -815,9 +870,9 @@
 
 class Run(models.Model):
     # each request may have multiple runs
-    request = models.ForeignKey(Request)
+    request = models.ForeignKey(Request, db_index=True)
 
-    status = models.ForeignKey(Status, db_index=True)
+    status = models.CharField(maxlength=100)
     started = models.DateTimeField(auto_now_add=True, editable=False)
     finished = models.DateTimeField(null=True, blank=True)
 
@@ -827,10 +882,10 @@
 
 class Job(models.Model):
     # each run may correspond to multiple jobs
-    run = models.ForeignKey(Run)
+    run = models.ForeignKey(Run, db_index=True)
     
     task = models.CharField(maxlength=100)
-    status = models.ForeignKey(Status, db_index=True)
+    status = models.CharField(maxlength=100)
     created = models.DateTimeField(auto_now_add=True, editable=False)
     started = models.DateTimeField(null=True, blank=True)
     finished = models.DateTimeField(null=True, blank=True)

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineos_parameters.pml
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineos_parameters.pml	2008-04-09 00:35:29 UTC (rev 11777)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineos_parameters.pml	2008-04-09 01:06:43 UTC (rev 11778)
@@ -11,28 +11,28 @@
         <property name="stations">stations</property>
 
         <!-- common -->
-        <property name="radial">{{ simulation.radial }}</property>
-        <property name="toroidal">{{ simulation.toroidal }}</property>
-        <property name="spheroidal">{{ simulation.spheroidal }}</property>
-        <property name="inner-core-toroidal">{{ simulation.ictoroidal }}</property>
+        <property name="radial">{{ parameters.radial }}</property>
+        <property name="toroidal">{{ parameters.toroidal }}</property>
+        <property name="spheroidal">{{ parameters.spheroidal }}</property>
+        <property name="inner-core-toroidal">{{ parameters.ictoroidal }}</property>
 
         <!-- minos_bran -->
-        <property name="eps">{{ simulation.eps }}</property>
-        <property name="wgrav">{{ simulation.wgrav }}*milli*hertz</property>
-        <property name="lmin">{{ simulation.lmin }}</property>
-        <property name="lmax">{{ simulation.lmax }}</property>
-        <property name="wmin">{{ simulation.wmin }}*milli*hertz</property>
-        <property name="wmax">{{ simulation.wmax }}*milli*hertz</property>
-        <property name="nmin">{{ simulation.nmin }}</property>
-        <property name="nmax">{{ simulation.nmax }}</property>
+        <property name="eps">{{ parameters.catalog.eps }}</property>
+        <property name="wgrav">{{ parameters.catalog.wgrav }}*milli*hertz</property>
+        <property name="lmin">{{ parameters.catalog.lmin }}</property>
+        <property name="lmax">{{ parameters.catalog.lmax }}</property>
+        <property name="wmin">{{ parameters.catalog.wmin }}*milli*hertz</property>
+        <property name="wmax">{{ parameters.catalog.wmax }}*milli*hertz</property>
+        <property name="nmin">{{ parameters.catalog.nmin }}</property>
+        <property name="nmax">{{ parameters.catalog.nmax }}</property>
 
         <!-- eigcon -->
-        <property name="max-depth">{{ simulation.max_depth }}*km</property>
+        <property name="max-depth">{{ parameters.catalog.max_depth }}*km</property>
 
         <!-- green -->
-        <property name="fmin">{{ simulation.fmin }}*milli*hertz</property>
-        <property name="fmax">{{ simulation.fmax }}*milli*hertz</property>
-        <property name="nsamples">{{ simulation.nsamples }}</property>
+        <property name="fmin">{{ parameters.fmin }}*milli*hertz</property>
+        <property name="fmax">{{ parameters.fmax }}*milli*hertz</property>
+        <property name="nsamples">{{ parameters.nsamples }}</property>
 
     </component>
 

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/run_list.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/run_list.py	2008-04-09 00:35:29 UTC (rev 11777)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/run_list.py	2008-04-09 01:06:43 UTC (rev 11778)
@@ -1,5 +1,5 @@
 (
     {% for object in object_list %}
-    { 'id': {{ object.id }}, 'status': '{{ object.status }}', 'simulation': {{ object.simulation.id }}, 'nodes': {{ object.simulation.nodes }} },
+    { 'id': {{ object.id }}, 'status': '{{ object.status }}', 'request': {{ object.request.id }}, 'code': {{ object.request.code }} },
     {% endfor %}
 )

Modified: cs/portal/trunk/seismo/SeismoWebPortal/views.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/views.py	2008-04-09 00:35:29 UTC (rev 11777)
+++ cs/portal/trunk/seismo/SeismoWebPortal/views.py	2008-04-09 01:06:43 UTC (rev 11778)
@@ -17,7 +17,8 @@
 from models import MineosModeCatalog, MineosModel, MineosParameters
 from models import Run, Job, OutputFile
 from models import FSNode, Folder
-from models import EventWorkspace, Request, Status
+from models import EventWorkspace, Request
+from models import CMTSolution as CMTSolutionModel
 from cmt import CMTSolution
 import config
 import gui
@@ -479,17 +480,6 @@
         return object_detail(request, desktop, view, Specfem3DGlobeParameters.objects.all(), object_id = objId)
     
     name = path.pop(0)
-            
-    if name == "mineos":
-        name = path.pop(0)
-        index = Index({
-            "parameters.pml": mineos_parameters_pml,
-            "event.txt": mineos_event_txt,
-            "stations.site": mineos_stations_site,
-            "stations.sitechan": mineos_stations_sitechan,
-            })
-        return index[name](request, sim_id = objId)
-    
     if path: raise Http404
 
     if name == "edit":
@@ -514,44 +504,35 @@
     if name == "delete":
         obj = get_object_or_404(Specfem3DGlobeParameters, id=objId)
         return moveObjectToTrash(obj, request, config.root + "/home/")
-    
-    index = Index({
-        "par_file.txt": par_file,
-        "parameters.pml": parameters_pml,
-        "stations.txt": stations_txt,
-        "events.txt": events_txt,
-        })
-    view = index[name]
-    return view(request, sim_id = objId)
 
+    raise Http404
 
-def par_file(request, sim_id):
+
+def par_file(request):
     from django.template import Context
 
     response = HttpResponse(mimetype='text/plain')
     #response['Content-Disposition'] = 'attachment; filename=parameters.xml'
 
-    simulation = get_object_or_404(Specfem3DGlobeParameters, id=sim_id)
-
+    parameters = Specfem3DGlobeParameters.objectFromSnapshot(request.parameters)
+    parameters.record_length = request.record_length
+    
     t = loader.get_template('SeismoWebPortal/par_file.txt')
-    c = Context({
-        'simulation': simulation,
-    })
+    c = Context({ 'simulation': parameters })
     response.write(t.render(c))
     return response
 
-def parameters_pml(request, sim_id):
+def parameters_pml(request):
     from django.template import Context
 
     response = HttpResponse(mimetype='text/xml')
     #response['Content-Disposition'] = 'attachment; filename=parameters.xml'
 
-    simulation = get_object_or_404(Specfem3DGlobeParameters, id=sim_id)
+    parameters = Specfem3DGlobeParameters.objectFromSnapshot(request.parameters)
+    parameters.record_length = request.record_length
 
     t = loader.get_template('SeismoWebPortal/parameters.pml')
-    c = Context({
-        'simulation': simulation,
-    })
+    c = Context({ 'simulation': parameters })
     response.write(t.render(c))
     return response
 
@@ -637,7 +618,7 @@
         errors = form.get_validation_errors(new_data)
         if not errors:
             form.save(email_template_name='registration/pwreset_email.txt',
-                      domain_override="the SPECFEM 3D GLOBE Web Portal")
+                      domain_override="the CIG Seismology Web Portal")
             return HttpResponseRedirect('%sdone/' % request.path)
     html = loader.render_to_string('registration/pwreset.html',
                                    {'form': forms.FormWrapper(form, new_data, errors)})
@@ -645,25 +626,34 @@
     desktop.activeWindow.selectWindow(reset)
     return desktop
 
-def events_txt(request, sim_id):
+def event_txt(request):
 
+    parameters = Specfem3DGlobeParameters.objectFromSnapshot(request.parameters)
+
+    sourceList = []
+    if request.event < 0:
+        event = Event.objects.get(id = -request.event)
+        for source in event.source_set.all():
+            sourceList.append(CMTSolution.createFromDBModel(source))
+    else:
+        cmt = CMTSolutionModel.objects.get(id = request.event)
+        sourceList.append(CMTSolution().initFromCMTSolutionModel(cmt))
+    
     response = HttpResponse(mimetype='text/plain')
 
-    simulation = get_object_or_404(Specfem3DGlobeParameters, id=sim_id)
+    for cmtSolution in sourceList:
 
-    count = simulation.events.source_set.count()
-    for event in simulation.events.source_set.all():
-        cmtSolution = CMTSolution.createFromDBModel(event)
-
         # NYI: Specfem requires this to be zero for one
         # source, and positive for others.  Set it to zero for
         # single-source events.  For multi-source kinematic
         # ruptures, for now we assume the user uploaded a
         # proper CMTSOLUTION file.
-        if count == 1:
+        if len(sourceList) == 1:
+            # Nowadays, the 'timeShift' is lost anyway, since we
+            # queried the CMTSolution table.
             cmtSolution.timeShift = 0.0
 
-        if simulation.zero_half_duration:
+        if parameters.zero_half_duration:
             cmtSolution.halfDuration = 0.0
         
         response.write(str(cmtSolution))
@@ -679,14 +669,10 @@
     return
 
 
-def stations_txt(request, sim_id):
+def stations_txt(request):
     response = HttpResponse(mimetype='text/plain')
-
-    simulation = get_object_or_404(Specfem3DGlobeParameters, id=sim_id)
-    stations = simulation.stations.station_set.all()
-
+    stations = request.stations.station_set.all()
     write_stations(stations, response)
-
     return response
 
 
@@ -792,6 +778,9 @@
 def notify_user_of_successful_run(run):
     from django.core.mail import send_mail
 
+    if True: # NYI
+        return
+
     sim = run.simulation
     user = sim.user
 
@@ -803,11 +792,11 @@
                "https://crust.geodynamics.org%s/simulations/%d/" % (config.root, sim.id),
                "",
                "Sincerely,",
-               "The SPECFEM 3D GLOBE Web Portal",
+               "The CIG Seismology Web Portal",
                ]
     message = "\n".join(message)
     
-    send_mail(subject, message, "SPECFEM 3D GLOBE Web Portal <portal at geodynamics.org>", [user.email], fail_silently=True)
+    send_mail(subject, message, "CIG Seismology Web Portal <portal at geodynamics.org>", [user.email], fail_silently=True)
     
     return
 
@@ -824,10 +813,12 @@
     if name == "create":
         if path: raise Http404
         manipulator = Model.AddManipulator()
+        action = "create"
     else:
         object_id = intOr404(name)
         if len(path) != 1 or path[0] != "update": raise Http404
         manipulator = Model.ChangeManipulator(object_id)
+        action = "update"
     
     if request.method == 'POST':
         response = HttpResponse(mimetype='text/plain')
@@ -885,7 +876,7 @@
                 request.session.delete_test_cookie()
                 help_login_hook(request, user)
                 notify_managers_of_new_user(request, user)
-                user.message_set.create(message="Welcome to the SPECFEM 3D GLOBE web portal!")
+                user.message_set.create(message="Welcome to the CIG Seismology Web Portal!")
                 return HttpResponseRedirect(config.root + '/')
     else:
         # Populate new_data with a 'flattened' version of the current data.
@@ -1293,18 +1284,25 @@
         print >>html, '<h3>%s</h3>' % ParameterClass.offering
         print >>html, '<table rules="groups" class="cool">'
         print >>html, '<thead>'
-        print >>html, '<tr><th>parameter set</th><th>status</th><th></th></tr>'
+        print >>html, '<tr><th>parameter set</th><th>status</th><th></th><th>output</th></tr>'
         print >>html, '</thead>'
         print >>html, '<tbody>'
         for i, ps in enumerate(ParameterClass.objects.all()):
             status = '<td>unavailable</td><td>%s</td>' % requestForm(workspace, ps)
+            output = '<td></td>'
             parameters = ps.snapshot(workspace)
             for request in requests[ParameterClass.code]:
                 if request.parameters == parameters:
-                    status = '<td colspan=2>%s</td>' % "waiting for dispatch"
+                    run = request.run
+                    status = '<td colspan=2>%s</td>' % run.status
+                    output = ''
+                    for job in run.job_set.all():
+                        for file in job.outputfile_set.all():
+                            output += '<li><a href="%s">%s</a>' % (file.url(), file.name)
+                    output = '<td><ul class=output>%s</ul></td>' % output
                     break
-            print >>html, '<tr class=%s><td><a href="%s">%s</a></td>%s</tr>' % (
-                (i % 2 and 'even' or 'odd'), ps.fsNode.url(), ps, status)
+            print >>html, '<tr class=%s><td><a href="%s">%s</a></td>%s%s</tr>' % (
+                (i % 2 and 'even' or 'odd'), ps.fsNode.url(), ps, status, output)
         print >>html, '</tbody>'
         print >>html, '</table>'
 
@@ -1328,10 +1326,41 @@
 
 
 def requests(request, path, desktop):
-    if not path or request.method != 'POST': raise Http404
+    if not path: raise Http404
+    
     name = path.pop(0)
-    if name != "new" or path: raise Http404
 
+    if name != "new":
+        # input file downloads
+        
+        objId = intOr404(name)
+        request = get_object_or_404(Request, id=objId)
+        if not path: raise Http404
+        name = path.pop(0)
+        if path: raise Http404
+
+        if request.code == Specfem3DGlobeParameters.code:
+            index = Index({
+                "par_file.txt": par_file,
+                "parameters.pml": parameters_pml,
+                "stations.txt": stations_txt,
+                "event.txt": event_txt,
+                })
+        elif request.code == MineosParameters.code:
+            index = Index({
+                "parameters.pml": mineos_parameters_pml,
+                "event.txt": mineos_event_txt,
+                "stations.site": mineos_stations_site,
+                "stations.sitechan": mineos_stations_sitechan,
+                "model.txt": mineos_model_txt,
+                })
+        else:
+            raise Http404
+
+        return index[name](request)
+
+    if path or request.method != 'POST': raise Http404
+    
     workspace = EventWorkspace.objects.get(id = int(request.POST['workspace']))
     code = int(request.POST['code'])
     if code == Specfem3DGlobeParameters.code:
@@ -1352,6 +1381,11 @@
     request.parameterData = Request.encodeParameters(parameterData)
 
     request.save()
+
+    Run.objects.create(
+        request = request,
+        status = "new",
+        )
     
     return HttpResponseRedirect(workspace.fsNode.url())
 
@@ -1953,60 +1987,61 @@
 # Mineos
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-def mineos_parameters_pml(request, sim_id):
+def mineos_parameters_pml(request):
     from django.template import Context
 
     response = HttpResponse(mimetype='text/xml')
 
-    simulation = get_object_or_404(Specfem3DGlobeParameters, id=sim_id)
+    parameters = MineosParameters.objectFromSnapshot(request.parameters)
+    parameters.record_length = request.record_length
 
     t = loader.get_template('SeismoWebPortal/mineos_parameters.pml')
-    c = Context({
-        'simulation': simulation,
-    })
+    c = Context({ 'parameters': parameters })
     response.write(t.render(c))
     return response
 
 
-def mineos_event_txt(request, sim_id):
+def mineos_event_txt(request):
     from math import log10, fabs, pow, ldexp
+    import datetime
     
     response = HttpResponse(mimetype='text/plain')
 
-    simulation = get_object_or_404(Specfem3DGlobeParameters, id=sim_id)
-    
-    for source in simulation.events.source_set.all():
-        cmt = CMTSolution.createFromDBModel(source)
+    if request.event < 0:
+        raise Http404
 
-        logs = [int(log10(fabs(x))) for x in (cmt.Mrr, cmt.Mtt, cmt.Mpp, cmt.Mrt, cmt.Mrp, cmt.Mtp)]
-        biggestLog = max(logs)
-        coefficient = pow(10.0, biggestLog)
+    cmt = CMTSolutionModel.objects.get(id = request.event)
+    cmt = CMTSolution().initFromCMTSolutionModel(cmt)
+
+    parameters = MineosParameters.objectFromSnapshot(request.parameters)
+
+    logs = [int(log10(fabs(x))) for x in (cmt.Mrr, cmt.Mtt, cmt.Mpp, cmt.Mrt, cmt.Mrp, cmt.Mtp)]
+    biggestLog = max(logs)
+    coefficient = pow(10.0, biggestLog)
         
-        response.write("%-8s %s %5.2f %5.2f %7.2f %6.2f %3.1f %4.1f %.2e %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %.1e 0 0 0 0 0 0\n" %
-                       (source.eventName[0:8],
-                        source.when.strftime("%Y %j %H %M"), cmt._second,
-                        cmt.latitude, cmt.longitude, cmt.depth,
-                        simulation.step,
-                        cmt.halfDuration, # negative?
-                        cmt.scalarSeismicMoment(), # will '+' cause trouble?
-                        cmt.Mrr / coefficient,
-                        cmt.Mtt / coefficient,
-                        cmt.Mpp / coefficient,
-                        cmt.Mrt / coefficient,
-                        cmt.Mrp / coefficient,
-                        cmt.Mtp / coefficient,
-                        coefficient,
-                        ))
+    response.write("%-8s %s %5.2f %5.2f %7.2f %6.2f %3.1f %4.1f %.2e %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %.1e 0 0 0 0 0 0\n" % (
+        "ZZZZZZZ",
+        datetime.datetime.now().strftime("%Y %j %H %M"), cmt._second,
+        cmt.latitude, cmt.longitude, cmt.depth,
+        parameters.step,
+        cmt.halfDuration, # negative?
+        cmt.scalarSeismicMoment(), # will '+' cause trouble?
+        cmt.Mrr / coefficient,
+        cmt.Mtt / coefficient,
+        cmt.Mpp / coefficient,
+        cmt.Mrt / coefficient,
+        cmt.Mrp / coefficient,
+        cmt.Mtp / coefficient,
+        coefficient,
+        ))
 
     return response
 
 
-def mineos_stations_site(request, sim_id):
+def mineos_stations_site(request):
     response = HttpResponse(mimetype='text/plain')
     
-    simulation = get_object_or_404(Specfem3DGlobeParameters, id=sim_id)
-
-    stations = simulation.stations.station_set.all()
+    stations = request.stations.station_set.all()
     ondate = 0
     offdate = -1
     statype = refsta = "-"
@@ -2023,12 +2058,10 @@
     return response
 
 
-def mineos_stations_sitechan(request, sim_id):
+def mineos_stations_sitechan(request):
     response = HttpResponse(mimetype='text/plain')
     
-    simulation = get_object_or_404(Specfem3DGlobeParameters, id=sim_id)
-
-    stations = simulation.stations.station_set.all()
+    stations = request.stations.station_set.all()
     chanid = -1
     
     # Mineos actually cares about the date range.  Stations that were
@@ -2051,6 +2084,13 @@
     return response
 
 
+def mineos_model_txt(request):
+    response = HttpResponse(mimetype='text/plain')
+    parameters = MineosParameters.objectFromSnapshot(request.parameters)
+    response.write(parameters.model.data)
+    return response
+
+
 def config_mineos_models(request, path, desktop):
     return uploadOnly(request, path, desktop,
                       UploadMineosModelManipulator(),



More information about the cig-commits mailing list