irie 0.0.4__py3-none-any.whl → 0.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of irie might be problematic. Click here for more details.

Files changed (62) hide show
  1. irie/apps/config.py +0 -1
  2. irie/apps/evaluation/identification.py +1 -1
  3. irie/apps/evaluation/models.py +3 -3
  4. irie/apps/evaluation/views.py +3 -3
  5. irie/apps/events/admin.py +2 -2
  6. irie/apps/events/migrations/0002_rename_event_eventrecord.py +19 -0
  7. irie/apps/events/migrations/0003_hazardevent.py +21 -0
  8. irie/apps/events/models.py +55 -5
  9. irie/apps/events/views.py +48 -3
  10. irie/apps/events/views_events.py +6 -10
  11. irie/apps/inventory/filters.py +37 -0
  12. irie/apps/inventory/models.py +7 -0
  13. irie/apps/inventory/urls.py +1 -0
  14. irie/apps/inventory/views.py +134 -227
  15. irie/apps/prediction/forms.py +4 -8
  16. irie/apps/prediction/metrics.py +0 -2
  17. irie/apps/prediction/migrations/0002_alter_predictormodel_protocol.py +18 -0
  18. irie/apps/prediction/models.py +4 -4
  19. irie/apps/prediction/predictor.py +18 -12
  20. irie/apps/prediction/runners/__init__.py +3 -398
  21. irie/apps/prediction/runners/hazus.py +579 -0
  22. irie/apps/prediction/runners/opensees/__init__.py +395 -0
  23. irie/apps/prediction/runners/{utilities.py → opensees/utilities.py} +7 -7
  24. irie/apps/prediction/runners/ssid.py +414 -0
  25. irie/apps/prediction/urls.py +1 -1
  26. irie/apps/prediction/views.py +45 -22
  27. irie/apps/site/view_sdof.py +2 -2
  28. irie/apps/templates/admin/base_site.html +3 -1
  29. irie/apps/templates/css/admin-extra.css +7 -0
  30. irie/apps/templates/includes/sidebar.html +17 -14
  31. irie/apps/templates/inventory/asset-event-summary.html +3 -2
  32. irie/apps/templates/inventory/asset-profile.html +126 -38
  33. irie/apps/templates/inventory/asset-table.html +191 -135
  34. irie/apps/templates/inventory/dashboard.html +105 -27
  35. irie/apps/templates/inventory/preamble.tex +131 -0
  36. irie/apps/templates/inventory/report.tex +59 -0
  37. irie/apps/templates/networks/corridor_table.html +2 -2
  38. irie/apps/templates/networks/networks.html +164 -0
  39. irie/apps/templates/networks/networks.js +2 -2
  40. irie/apps/templates/prediction/asset-predictors.html +6 -6
  41. irie/apps/templates/prediction/form-submission.html +3 -3
  42. irie/apps/templates/prediction/hazus/event.html +33 -0
  43. irie/apps/templates/prediction/hazus/history.html +1 -0
  44. irie/apps/templates/prediction/hazus/history.js +44 -0
  45. irie/apps/templates/prediction/{new-predictor.html → new-runner.html} +12 -8
  46. irie/apps/templates/site/index.html +29 -47
  47. irie/core/urls.py +7 -2
  48. irie/init/__main__.py +2 -0
  49. irie/init/bridges.py +5 -3
  50. irie/init/management/commands/init_assets.py +24 -45
  51. irie/init/management/commands/init_corridors.py +3 -6
  52. irie/init/management/commands/init_predictors.py +23 -8
  53. irie/post/__main__.py +88 -0
  54. {irie-0.0.4.dist-info → irie-0.0.6.dist-info}/METADATA +5 -3
  55. {irie-0.0.4.dist-info → irie-0.0.6.dist-info}/RECORD +62 -48
  56. /irie/apps/prediction/runners/{metrics.py → opensees/metrics.py} +0 -0
  57. /irie/apps/prediction/runners/{xmlutils.py → opensees/xmlutils.py} +0 -0
  58. /irie/apps/prediction/runners/{zipped.py → opensees/zipped.py} +0 -0
  59. /irie/init/data/{04.tar → nbi/04.tar} +0 -0
  60. {irie-0.0.4.dist-info → irie-0.0.6.dist-info}/WHEEL +0 -0
  61. {irie-0.0.4.dist-info → irie-0.0.6.dist-info}/entry_points.txt +0 -0
  62. {irie-0.0.4.dist-info → irie-0.0.6.dist-info}/top_level.txt +0 -0
irie/apps/config.py CHANGED
@@ -4,4 +4,3 @@ class AppsConfig(AppConfig):
4
4
  default_auto_field = "django.db.models.BigAutoField"
5
5
  name = "irie.apps"
6
6
  label = "irie_apps"
7
-
@@ -26,7 +26,7 @@ import json
26
26
  from collections import defaultdict
27
27
 
28
28
  import numpy as np
29
- from irie.apps.events.models import Event
29
+ from irie.apps.events.models import EventRecord
30
30
  from irie.apps.site.view_utils import raise404
31
31
  from irie.apps.inventory.models import Asset
32
32
 
@@ -14,18 +14,18 @@ import logging
14
14
  from threading import Thread
15
15
  from django.db import models
16
16
 
17
- from irie.apps.events.models import Event
17
+ from irie.apps.events.models import EventRecord
18
18
  from irie.apps.inventory.models import Asset
19
19
  from .daemon import LiveEvaluation
20
20
 
21
21
  class Evaluation(models.Model):
22
22
  id = models.BigAutoField(primary_key=True)
23
- event = models.ForeignKey(Event, on_delete=models.CASCADE)
23
+ event = models.ForeignKey(EventRecord, on_delete=models.CASCADE)
24
24
  asset = models.ForeignKey(Asset, on_delete=models.CASCADE, null=True)
25
25
  evaluation_data = models.JSONField(default=dict)
26
26
 
27
27
  @classmethod
28
- def create(cls, event: Event, asset: Asset, data: dict = None):
28
+ def create(cls, event: EventRecord, asset: Asset, data: dict = None):
29
29
  evaluation = cls()
30
30
  evaluation.event = event
31
31
  evaluation.asset = asset
@@ -20,13 +20,13 @@ from rest_framework.decorators import api_view, permission_classes
20
20
  from rest_framework.permissions import IsAuthenticated
21
21
 
22
22
  from .models import Evaluation
23
- from irie.apps.events.models import Event
23
+ from irie.apps.events.models import EventRecord
24
24
  from irie.apps.inventory import views as inventory
25
25
  from irie.apps.inventory.models import Asset
26
26
 
27
27
  def _evals_and_events(asset):
28
28
  evals = Evaluation.objects.filter(asset_id=asset.id)
29
- events = (Event.objects.get(id=eval.event.id) for eval in evals)
29
+ events = (EventRecord.objects.get(id=eval.event.id) for eval in evals)
30
30
  return evals, events
31
31
 
32
32
  @api_view(['GET'])
@@ -56,7 +56,7 @@ def get_evaluations(request):
56
56
  } for eval in evals
57
57
  ],
58
58
  "summary": {
59
- "SPECTRAL_SHIFT_IDENTIFICATION": inventory._ssid_stats(
59
+ "SPECTRAL_SHIFT_IDENTIFICATION": inventory.ssid_stats(
60
60
  events, #[inventory._find_ssid(event_id=event.id) for event in events],
61
61
  "period"
62
62
  )
irie/apps/events/admin.py CHANGED
@@ -4,6 +4,6 @@
4
4
  #
5
5
  #===----------------------------------------------------------------------===#
6
6
  from django.contrib import admin
7
- from .models import Event
7
+ from .models import HazardEvent, EventRecord
8
8
 
9
- admin.site.register(Event)
9
+ admin.site.register(EventRecord)
@@ -0,0 +1,19 @@
1
+ # Generated by Django 5.1.2 on 2024-12-08 03:44
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('irie_apps_evaluation', '0001_initial'),
10
+ ('irie_apps_events', '0001_initial'),
11
+ ('irie_apps_inventory', '0001_initial'),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.RenameModel(
16
+ old_name='Event',
17
+ new_name='EventRecord',
18
+ ),
19
+ ]
@@ -0,0 +1,21 @@
1
+ # Generated by Django 5.1.2 on 2024-12-08 03:49
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('irie_apps_events', '0002_rename_event_eventrecord'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name='HazardEvent',
15
+ fields=[
16
+ ('id', models.BigAutoField(primary_key=True, serialize=False)),
17
+ ('name', models.CharField(max_length=20)),
18
+ ('records', models.ManyToManyField(related_name='event', to='irie_apps_events.eventrecord')),
19
+ ],
20
+ ),
21
+ ]
@@ -18,7 +18,7 @@ from django.core.mail import send_mail
18
18
  from irie.apps.inventory.models import Asset
19
19
 
20
20
 
21
- class Event(models.Model):
21
+ class EventRecord(models.Model):
22
22
  id = models.BigAutoField(primary_key=True)
23
23
  upload_date = models.DateField(blank=False)
24
24
  event_file = models.FileField(upload_to='events', blank=True)
@@ -32,7 +32,7 @@ class Event(models.Model):
32
32
  asset = models.ForeignKey(Asset, on_delete=models.CASCADE)
33
33
 
34
34
  def __str__(self):
35
- return f"{self.cesmd} - {self.record_identifier}"
35
+ return f"{self.cesmd} - {self.motion_data.get('event_date', '')}"
36
36
 
37
37
  class Meta:
38
38
  ordering = ["-id"]
@@ -43,18 +43,68 @@ class Event(models.Model):
43
43
 
44
44
  @property
45
45
  def pga(self):
46
- return abs(self.motion_data["peak_accel"])/980.
46
+ return round(abs(self.motion_data["peak_accel"])/980.665, 2)
47
+
48
+ def plot_accel(self):
49
+ import io
50
+ import json
51
+ import base64
52
+ import quakeio
53
+ import matplotlib
54
+ matplotlib.use("Agg")
55
+ import matplotlib.pyplot as plt
56
+ from mdof.utilities.printing import plot_io
57
+ from mdof.utilities.config import extract_channels, create_time_vector
58
+
59
+ try:
60
+ import scienceplots
61
+ plt.style.use(["science"])
62
+ except ImportError:
63
+ pass
64
+
65
+
66
+ evnt = quakeio.read(self.event_file.path, format="csmip.zip")
67
+ try:
68
+ channels = json.loads(self.asset.bridge_sensors[2:-1])
69
+ outputs,dt = extract_channels(evnt, channels)
70
+ *_, time = create_time_vector(len(outputs[0]), dt)
71
+ except:
72
+ return None
73
+
74
+ try:
75
+ inputs,dt = extract_channels(evnt, json.loads(self.asset.ground_sensors[2:-1]))
76
+
77
+ fig = plot_io(inputs, outputs, time)
78
+ except:
79
+
80
+ fig, ax = plt.subplots()
81
+ for output in outputs:
82
+ ax.plot(time, output)
83
+
84
+ buffer = io.BytesIO()
85
+ fig.savefig(buffer, format="png")
86
+ buffer.seek(0)
87
+ return base64.b64encode(buffer.read()).decode("utf-8")
88
+
89
+ class HazardEvent(models.Model):
90
+ id = models.BigAutoField(primary_key=True)
91
+ name = models.CharField(max_length=20)
92
+ records = models.ManyToManyField('EventRecord', related_name='event')
93
+
94
+ def __str__(self):
95
+ return f"{self.name} ({self.records.count()})"
96
+
47
97
 
48
98
 
49
99
  # Signal to delete the event file when the model instance is deleted
50
- @receiver(post_delete, sender=Event)
100
+ @receiver(post_delete, sender=EventRecord)
51
101
  def delete_file_on_delete(sender, instance, **kwargs):
52
102
  if instance.event_file:
53
103
  if os.path.isfile(instance.event_file.path):
54
104
  os.remove(instance.event_file.path)
55
105
 
56
106
  # Signal to delete the old event file when the file is replaced
57
- @receiver(pre_save, sender=Event)
107
+ @receiver(pre_save, sender=EventRecord)
58
108
  def delete_file_on_change(sender, instance, **kwargs):
59
109
  if not instance.pk:
60
110
  return False
irie/apps/events/views.py CHANGED
@@ -5,7 +5,7 @@ from django.core.paginator import Paginator
5
5
  from django.http import HttpResponse
6
6
  from django.contrib.auth.decorators import login_required
7
7
 
8
- from irie.apps.events.models import Event
8
+ from irie.apps.events.models import EventRecord
9
9
  from irie.apps.site.view_utils import raise404
10
10
 
11
11
 
@@ -27,10 +27,55 @@ def event_table(request):
27
27
  asset = request.GET.get("asset", None)
28
28
 
29
29
  if asset is not None:
30
- events = [i for i in reversed(sorted(Event.objects.filter(asset=asset),
30
+ events = [i for i in reversed(sorted(EventRecord.objects.filter(asset=asset),
31
31
  key=lambda x: x.motion_data["event_date"]))]
32
32
  else:
33
- events = [i for i in reversed(sorted(Event.objects.all(),
33
+ events = [i for i in reversed(sorted(EventRecord.objects.all(),
34
+ key=lambda x: x.motion_data["event_date"]))]
35
+
36
+ # Paginator for 10 items per page
37
+ paginator = Paginator(events, 15)
38
+
39
+
40
+ # reversed(sorted(Event.objects.all(),
41
+ # key=lambda x: x.motion_data["event_date"]))
42
+ context["events"] = paginator.get_page(page)
43
+
44
+
45
+ html_template = loader.get_template("events/" + page_template)
46
+
47
+ try:
48
+ return HttpResponse(html_template.render(context, request))
49
+
50
+ except Exception as e:
51
+ if "DEBUG" in os.environ and os.environ["DEBUG"]:
52
+ raise e
53
+ html_template = loader.get_template("site/page-500.html")
54
+ return HttpResponse(html_template.render(context, request))
55
+
56
+
57
+ @login_required(login_url="/login/")
58
+ def event_collection(request):
59
+ """
60
+ This view generates the event table page. It uses the event-table.html
61
+ """
62
+ context = {}
63
+ page_template = "event-table.html"
64
+ context["segment"] = "event-table.html"
65
+
66
+ page = request.GET.get("page", 1)
67
+ try:
68
+ page = int(page)
69
+ except:
70
+ page = 1
71
+
72
+ asset = request.GET.get("asset", None)
73
+
74
+ if asset is not None:
75
+ events = [i for i in reversed(sorted(EventRecord.objects.filter(asset=asset),
76
+ key=lambda x: x.motion_data["event_date"]))]
77
+ else:
78
+ events = [i for i in reversed(sorted(EventRecord.objects.all(),
34
79
  key=lambda x: x.motion_data["event_date"]))]
35
80
 
36
81
  # Paginator for 10 items per page
@@ -5,7 +5,6 @@
5
5
  #===----------------------------------------------------------------------===#
6
6
  import json
7
7
  import datetime
8
- from threading import Thread
9
8
  from django.shortcuts import render
10
9
  from django.core.exceptions import ObjectDoesNotExist
11
10
  from django.shortcuts import HttpResponse
@@ -16,10 +15,8 @@ from rest_framework.decorators import api_view, permission_classes, parser_class
16
15
  from rest_framework import status
17
16
  from rest_framework.permissions import IsAuthenticated
18
17
 
19
- from .models import Event
18
+ from .models import EventRecord
20
19
  from irie.apps.inventory.models import Asset
21
- # from irie.apps.evaluation.evaluation import (run_evaluation,
22
- # add_evaluation)
23
20
  from irie.apps.evaluation.models import Evaluation
24
21
  import quakeio
25
22
 
@@ -33,7 +30,6 @@ def serialize_event(event):
33
30
  else:
34
31
  serialized["event_file"] = None
35
32
 
36
- #serialized["data_str"] = json.loads(event.data_str) if event.data_str else {}
37
33
  return serialized
38
34
 
39
35
 
@@ -93,10 +89,10 @@ def save_event(request, event, success_status):
93
89
  # CREATE EVENT
94
90
  if event is None:
95
91
  # Doing a PUT
96
- event = Event.objects.filter(record_identifier=rec_id).first()
92
+ event = EventRecord.objects.filter(record_identifier=rec_id).first()
97
93
  if event is None:
98
94
  print("PUT: creating", rec_id, "\n\n")
99
- event = Event()
95
+ event = EventRecord()
100
96
  else:
101
97
  print("PUT: updating", rec_id, "\n\n")
102
98
  upload_date = event.upload_date
@@ -168,7 +164,7 @@ def events(request):
168
164
  # return HttpResponse(json.dumps({"detail": "Not authorized"}), status=status.HTTP_401_UNAUTHORIZED)
169
165
 
170
166
  if request.method == "GET":
171
- events_data = Event.objects.all()
167
+ events_data = EventRecord.objects.all()
172
168
 
173
169
  events_count = events_data.count()
174
170
 
@@ -180,7 +176,7 @@ def events(request):
180
176
  return HttpResponse(json.dumps({"count": events_count, "data": events_data}), status=status.HTTP_200_OK)
181
177
 
182
178
  elif request.method == "POST":
183
- event = Event()
179
+ event = EventRecord()
184
180
  return save_event(request, event, status.HTTP_201_CREATED)
185
181
 
186
182
  elif request.method == "PUT":
@@ -197,7 +193,7 @@ def event(request, event_id):
197
193
  # return HttpResponse(json.dumps({"detail": "Not authorized"}), status=status.HTTP_401_UNAUTHORIZED)
198
194
 
199
195
  try:
200
- event = Event.objects.get(pk=event_id)
196
+ event = EventRecord.objects.get(pk=event_id)
201
197
  except ObjectDoesNotExist:
202
198
  return HttpResponse(json.dumps({"detail": "Not found"}), status=status.HTTP_404_NOT_FOUND)
203
199
 
@@ -0,0 +1,37 @@
1
+ import django_filters
2
+ from django.forms import CheckboxInput
3
+
4
+ class AssetFilter(django_filters.FilterSet):
5
+ search = django_filters.CharFilter(
6
+ lookup_expr="icontains",
7
+ field_name="calid",
8
+ label='Search'
9
+ )
10
+
11
+ cesmd_not_null = django_filters.BooleanFilter(
12
+ label='On CESMD',
13
+ widget=CheckboxInput(),
14
+ method='filter_cesmd_exists'
15
+ )
16
+
17
+ is_complete = django_filters.BooleanFilter(
18
+ field_name='is_complete',
19
+ label='Is Complete',
20
+ widget=CheckboxInput()
21
+ )
22
+ district = django_filters.CharFilter(
23
+ label='District',
24
+ method='filter_district'
25
+ )
26
+
27
+ def filter_cesmd_exists(self, queryset, name, value):
28
+ if value: # Checkbox is checked
29
+ return queryset.exclude(cesmd__isnull=True).exclude(cesmd__exact='')
30
+ return queryset
31
+
32
+ def filter_district(self, queryset, name, value):
33
+ return [
34
+ asset for asset in queryset if (
35
+ asset.nbi_data and asset.nbi_data["NBI_BRIDGE"]["Highway Agency District"] == value
36
+ )
37
+ ]
@@ -51,6 +51,13 @@ class Asset(models.Model):
51
51
  for p in PredictorModel.objects.filter(asset=self)
52
52
  }
53
53
 
54
+ @property
55
+ def rendering(self):
56
+ from irie.apps.prediction.models import PredictorModel
57
+ for predictor in PredictorModel.objects.filter(asset=self):
58
+ if predictor.render_file:
59
+ return predictor.render_file.url
60
+
54
61
  @property
55
62
  def coordinates(self):
56
63
  if self.nbi_data:
@@ -12,6 +12,7 @@ from django.urls import path, re_path
12
12
  from irie.apps.inventory import views
13
13
 
14
14
  urlpatterns = [
15
+ path("summarize/", views.asset_event_report),
15
16
  path("dashboard/", views.dashboard, name="dashboard"),
16
17
  path("dashboard.html", views.dashboard),
17
18
  path("dashboard/demo", views.dashboard),