irie 0.0.5__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.
- irie/apps/config.py +0 -1
- irie/apps/evaluation/identification.py +1 -1
- irie/apps/evaluation/models.py +3 -3
- irie/apps/evaluation/views.py +3 -3
- irie/apps/events/admin.py +2 -2
- irie/apps/events/migrations/0002_rename_event_eventrecord.py +19 -0
- irie/apps/events/migrations/0003_hazardevent.py +21 -0
- irie/apps/events/models.py +55 -5
- irie/apps/events/views.py +48 -3
- irie/apps/events/views_events.py +6 -10
- irie/apps/inventory/filters.py +37 -0
- irie/apps/inventory/models.py +7 -0
- irie/apps/inventory/urls.py +1 -0
- irie/apps/inventory/views.py +134 -227
- irie/apps/prediction/forms.py +4 -8
- irie/apps/prediction/metrics.py +0 -2
- irie/apps/prediction/migrations/0002_alter_predictormodel_protocol.py +18 -0
- irie/apps/prediction/models.py +4 -4
- irie/apps/prediction/predictor.py +18 -12
- irie/apps/prediction/runners/__init__.py +3 -398
- irie/apps/prediction/runners/hazus.py +579 -0
- irie/apps/prediction/runners/opensees/__init__.py +395 -0
- irie/apps/prediction/runners/{utilities.py → opensees/utilities.py} +7 -7
- irie/apps/prediction/runners/ssid.py +414 -0
- irie/apps/prediction/urls.py +1 -1
- irie/apps/prediction/views.py +45 -22
- irie/apps/site/view_sdof.py +2 -2
- irie/apps/templates/admin/base_site.html +3 -1
- irie/apps/templates/css/admin-extra.css +7 -0
- irie/apps/templates/includes/sidebar.html +17 -14
- irie/apps/templates/inventory/asset-event-summary.html +3 -2
- irie/apps/templates/inventory/asset-profile.html +126 -38
- irie/apps/templates/inventory/asset-table.html +191 -135
- irie/apps/templates/inventory/dashboard.html +105 -27
- irie/apps/templates/inventory/preamble.tex +131 -0
- irie/apps/templates/inventory/report.tex +59 -0
- irie/apps/templates/networks/corridor_table.html +2 -2
- irie/apps/templates/networks/networks.html +164 -0
- irie/apps/templates/prediction/asset-predictors.html +6 -6
- irie/apps/templates/prediction/form-submission.html +3 -3
- irie/apps/templates/prediction/hazus/event.html +33 -0
- irie/apps/templates/prediction/hazus/history.html +1 -0
- irie/apps/templates/prediction/hazus/history.js +44 -0
- irie/apps/templates/prediction/{new-predictor.html → new-runner.html} +12 -8
- irie/apps/templates/site/index.html +29 -47
- irie/core/urls.py +7 -2
- irie/init/__main__.py +2 -0
- irie/init/bridges.py +5 -3
- irie/init/management/commands/init_assets.py +24 -45
- irie/init/management/commands/init_corridors.py +3 -6
- irie/init/management/commands/init_predictors.py +23 -8
- irie/post/__main__.py +88 -0
- {irie-0.0.5.dist-info → irie-0.0.6.dist-info}/METADATA +5 -3
- {irie-0.0.5.dist-info → irie-0.0.6.dist-info}/RECORD +61 -47
- /irie/apps/prediction/runners/{metrics.py → opensees/metrics.py} +0 -0
- /irie/apps/prediction/runners/{xmlutils.py → opensees/xmlutils.py} +0 -0
- /irie/apps/prediction/runners/{zipped.py → opensees/zipped.py} +0 -0
- /irie/init/data/{04.tar → nbi/04.tar} +0 -0
- {irie-0.0.5.dist-info → irie-0.0.6.dist-info}/WHEEL +0 -0
- {irie-0.0.5.dist-info → irie-0.0.6.dist-info}/entry_points.txt +0 -0
- {irie-0.0.5.dist-info → irie-0.0.6.dist-info}/top_level.txt +0 -0
irie/apps/config.py
CHANGED
|
@@ -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
|
|
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
|
|
irie/apps/evaluation/models.py
CHANGED
|
@@ -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
|
|
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(
|
|
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:
|
|
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
|
irie/apps/evaluation/views.py
CHANGED
|
@@ -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
|
|
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 = (
|
|
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.
|
|
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
|
@@ -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
|
+
]
|
irie/apps/events/models.py
CHANGED
|
@@ -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
|
|
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.
|
|
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=
|
|
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=
|
|
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
|
|
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(
|
|
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(
|
|
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
|
irie/apps/events/views_events.py
CHANGED
|
@@ -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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
+
]
|
irie/apps/inventory/models.py
CHANGED
|
@@ -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:
|
irie/apps/inventory/urls.py
CHANGED
|
@@ -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),
|