irie 0.0.50__py3-none-any.whl → 0.0.52__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/inventory/filters.py +11 -29
- irie/apps/inventory/models.py +3 -3
- irie/apps/inventory/views.py +12 -2
- irie/apps/prediction/admin.py +2 -1
- irie/apps/prediction/migrations/0004_sensorassignment.py +31 -0
- irie/apps/prediction/migrations/0005_remove_sensorassignment_offset_x_and_more.py +53 -0
- irie/apps/prediction/migrations/0006_remove_sensorassignment_show_x_and_more.py +25 -0
- irie/apps/prediction/models.py +22 -3
- irie/apps/prediction/runners/__init__.py +13 -3
- irie/apps/prediction/runners/opensees/__init__.py +114 -62
- irie/apps/prediction/runners/ssid.py +14 -13
- irie/apps/prediction/urls.py +12 -7
- irie/apps/prediction/views.py +80 -23
- irie/apps/static/assets/css/brace.css +5 -31
- irie/apps/static/assets/css/brace.css.map +1 -1
- irie/apps/static/assets/css/brace.min.css +2 -2
- irie/apps/templates/components/json-table.html +1 -0
- irie/apps/templates/includes/paginate.js +6 -0
- irie/apps/templates/includes/scripts.html +7 -20
- irie/apps/templates/inventory/asset-on-map.html +5 -5
- irie/apps/templates/inventory/sensor-upload.html +97 -262
- irie/apps/templates/networks/{networks.html → _networks.html} +0 -1
- irie/apps/templates/networks/networks.js +6 -4
- irie/apps/templates/prediction/asset-predictors.html +41 -47
- irie/apps/templates/prediction/{form-submission.html → create-mdof.html} +0 -21
- irie/apps/templates/prediction/new-runner.html +0 -20
- irie/apps/templates/prediction/predictor-profile.html +8 -134
- irie/apps/templates/prediction/viewer/veux-viewer.js +186 -0
- irie/apps/templates/prediction/xara-profile.html +221 -0
- irie/apps/templates/sensors/render-sensors.js +152 -0
- {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/METADATA +2 -3
- {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/RECORD +36 -29
- {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/WHEEL +1 -1
- /irie/apps/templates/prediction/{predictor-upload.html → create-model.html} +0 -0
- {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/entry_points.txt +0 -0
- {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/top_level.txt +0 -0
irie/apps/inventory/filters.py
CHANGED
|
@@ -5,37 +5,32 @@ class AssetFilter(django_filters.FilterSet):
|
|
|
5
5
|
search = django_filters.CharFilter(
|
|
6
6
|
lookup_expr="icontains",
|
|
7
7
|
field_name="calid",
|
|
8
|
-
label=
|
|
8
|
+
label="Search"
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
cesmd_not_null = django_filters.BooleanFilter(
|
|
12
|
-
label=
|
|
12
|
+
label="Instrumented",
|
|
13
13
|
widget=CheckboxInput(),
|
|
14
|
-
method=
|
|
14
|
+
method="filter_cesmd_exists"
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
is_streaming = django_filters.BooleanFilter(
|
|
18
|
-
# field_name=
|
|
19
|
-
label=
|
|
18
|
+
# field_name="is_complete",
|
|
19
|
+
label="Streaming",
|
|
20
20
|
widget=CheckboxInput(),
|
|
21
|
-
method=
|
|
21
|
+
method="filter_is_streaming"
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
district = django_filters.CharFilter(
|
|
25
|
-
label=
|
|
26
|
-
method=
|
|
25
|
+
label="District",
|
|
26
|
+
method="filter_district"
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
max_year = django_filters.NumberFilter(
|
|
30
|
-
label=
|
|
31
|
-
method=
|
|
32
|
-
# widget=django_filters.widgets.DateInput(attrs={'type': 'date'})
|
|
30
|
+
label="Max Year",
|
|
31
|
+
method="filter_year"
|
|
33
32
|
)
|
|
34
|
-
|
|
35
|
-
# label='Max Year',
|
|
36
|
-
# field_name='nbi_data__NBI_BRIDGE__Year Built',
|
|
37
|
-
# lookup_expr='lte'
|
|
38
|
-
# )
|
|
33
|
+
|
|
39
34
|
def filter_year(self, queryset, name, value):
|
|
40
35
|
ids = {
|
|
41
36
|
asset.id for asset in queryset if (
|
|
@@ -43,19 +38,6 @@ class AssetFilter(django_filters.FilterSet):
|
|
|
43
38
|
)
|
|
44
39
|
}
|
|
45
40
|
return queryset.filter(id__in=ids)
|
|
46
|
-
if value:
|
|
47
|
-
return queryset.filter(
|
|
48
|
-
nbi_data__NBI_BRIDGE__Year_Built__lte=int(value) #.year
|
|
49
|
-
)
|
|
50
|
-
return
|
|
51
|
-
|
|
52
|
-
if value:
|
|
53
|
-
filtered_ids = [
|
|
54
|
-
asset.id for asset in queryset if (
|
|
55
|
-
asset.nbi_data and asset.nbi_data["NBI_BRIDGE"]["Year Built"] <= value.year
|
|
56
|
-
)
|
|
57
|
-
]
|
|
58
|
-
return queryset.filter(id__in=filtered_ids)
|
|
59
41
|
|
|
60
42
|
|
|
61
43
|
def filter_cesmd_exists(self, queryset, name, value):
|
irie/apps/inventory/models.py
CHANGED
|
@@ -63,7 +63,7 @@ class Asset(models.Model):
|
|
|
63
63
|
from irie.apps.prediction.models import PredictorModel
|
|
64
64
|
return {
|
|
65
65
|
p.name: PREDICTOR_TYPES[p.protocol](p)
|
|
66
|
-
for p in PredictorModel.objects.filter(asset=self)
|
|
66
|
+
for p in reversed(PredictorModel.objects.filter(asset=self))
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
@property
|
|
@@ -123,7 +123,7 @@ class SensorGroup(models.Model):
|
|
|
123
123
|
# network = models.CharField(max_length=100)
|
|
124
124
|
# events = None
|
|
125
125
|
def __str__(self):
|
|
126
|
-
return f"{self.
|
|
126
|
+
return f"{self.asset.calid} - {self.name} ({self.datum})"
|
|
127
127
|
|
|
128
128
|
class Sensor(models.Model):
|
|
129
129
|
# class Status:
|
|
@@ -141,7 +141,7 @@ class Sensor(models.Model):
|
|
|
141
141
|
group = models.ForeignKey(SensorGroup, related_name="sensors", on_delete=models.RESTRICT)
|
|
142
142
|
|
|
143
143
|
def __str__(self):
|
|
144
|
-
return f"{self.name} ({self.group.name})"
|
|
144
|
+
return f"{self.group.asset.calid} - {self.name} ({self.group.name})"
|
|
145
145
|
|
|
146
146
|
|
|
147
147
|
|
irie/apps/inventory/views.py
CHANGED
|
@@ -24,6 +24,7 @@ from irie.apps.events.models import EventRecord
|
|
|
24
24
|
from irie.apps.site.view_utils import raise404
|
|
25
25
|
from irie.apps.inventory.models import Asset, SensorGroup, Sensor, Datum
|
|
26
26
|
from irie.apps.inventory.forms import SensorGroupForm, SensorForm, SensorFormSet
|
|
27
|
+
from irie.apps.prediction.models import PredictorModel
|
|
27
28
|
from .filters import AssetFilter
|
|
28
29
|
# Predictors
|
|
29
30
|
from irie.apps.prediction.runners.hazus import hazus_fragility
|
|
@@ -336,6 +337,9 @@ def asset_profile(request, calid):
|
|
|
336
337
|
except Exception as e:
|
|
337
338
|
if "DEBUG" in os.environ and os.environ["DEBUG"]:
|
|
338
339
|
raise e
|
|
340
|
+
import sys
|
|
341
|
+
print(e, file=sys.stderr)
|
|
342
|
+
print(e)
|
|
339
343
|
html_template = loader.get_template("site/page-500.html")
|
|
340
344
|
return HttpResponse(html_template.render(context, request))
|
|
341
345
|
|
|
@@ -439,12 +443,18 @@ def sensor_upload(request, calid):
|
|
|
439
443
|
group_form = SensorGroupForm(asset=asset)
|
|
440
444
|
formset = SensorFormSet()
|
|
441
445
|
|
|
442
|
-
|
|
446
|
+
context = {
|
|
443
447
|
"group_form": group_form,
|
|
444
448
|
"formset": formset,
|
|
449
|
+
"renderings": [
|
|
450
|
+
{"name": predictor.name, "glb": predictor.render_file.url}
|
|
451
|
+
for predictor in PredictorModel.objects.filter(asset=asset, protocol="IRIE_PREDICTOR_V1")
|
|
452
|
+
if predictor.render_file and predictor.render_file.url
|
|
453
|
+
],
|
|
445
454
|
"asset": asset,
|
|
446
455
|
"datums": list(datums)
|
|
447
|
-
}
|
|
456
|
+
}
|
|
457
|
+
return render(request, "inventory/sensor-upload.html", context)
|
|
448
458
|
|
|
449
459
|
|
|
450
460
|
def _filter_asset_table(request):
|
irie/apps/prediction/admin.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#
|
|
5
5
|
#===----------------------------------------------------------------------===#
|
|
6
6
|
from django.contrib import admin
|
|
7
|
-
from .models import PredictorModel
|
|
7
|
+
from .models import PredictorModel, SensorAssignment
|
|
8
8
|
|
|
9
9
|
admin.site.register(PredictorModel)
|
|
10
|
+
admin.site.register(SensorAssignment)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Generated by Django 5.1.2 on 2025-04-28 01:52
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('apps_prediction', '0003_alter_predictormodel_protocol'),
|
|
11
|
+
('irie_apps_inventory', '0008_alter_sensor_dx_alter_sensor_dy_alter_sensor_dz_and_more'),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.CreateModel(
|
|
16
|
+
name='SensorAssignment',
|
|
17
|
+
fields=[
|
|
18
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
19
|
+
('node', models.IntegerField()),
|
|
20
|
+
('role', models.CharField(choices=[('input', 'Input'), ('output', 'Output')], max_length=16)),
|
|
21
|
+
('orient_z', models.FloatField()),
|
|
22
|
+
('orient_x', models.FloatField(default=0.0)),
|
|
23
|
+
('orient_y', models.FloatField(default=0.0)),
|
|
24
|
+
('offset_x', models.FloatField(default=0.0)),
|
|
25
|
+
('offset_y', models.FloatField(default=0.0)),
|
|
26
|
+
('offset_z', models.FloatField(default=0.0)),
|
|
27
|
+
('predictor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apps_prediction.predictormodel')),
|
|
28
|
+
('sensor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='irie_apps_inventory.sensor')),
|
|
29
|
+
],
|
|
30
|
+
),
|
|
31
|
+
]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Generated by Django 5.1.2 on 2025-04-28 02:12
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('apps_prediction', '0004_sensorassignment'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.RemoveField(
|
|
14
|
+
model_name='sensorassignment',
|
|
15
|
+
name='offset_x',
|
|
16
|
+
),
|
|
17
|
+
migrations.RemoveField(
|
|
18
|
+
model_name='sensorassignment',
|
|
19
|
+
name='offset_y',
|
|
20
|
+
),
|
|
21
|
+
migrations.RemoveField(
|
|
22
|
+
model_name='sensorassignment',
|
|
23
|
+
name='offset_z',
|
|
24
|
+
),
|
|
25
|
+
migrations.AddField(
|
|
26
|
+
model_name='sensorassignment',
|
|
27
|
+
name='show_x',
|
|
28
|
+
field=models.FloatField(default=0),
|
|
29
|
+
preserve_default=False,
|
|
30
|
+
),
|
|
31
|
+
migrations.AddField(
|
|
32
|
+
model_name='sensorassignment',
|
|
33
|
+
name='show_y',
|
|
34
|
+
field=models.FloatField(default=0),
|
|
35
|
+
preserve_default=False,
|
|
36
|
+
),
|
|
37
|
+
migrations.AddField(
|
|
38
|
+
model_name='sensorassignment',
|
|
39
|
+
name='show_z',
|
|
40
|
+
field=models.FloatField(default=0),
|
|
41
|
+
preserve_default=False,
|
|
42
|
+
),
|
|
43
|
+
migrations.AlterField(
|
|
44
|
+
model_name='sensorassignment',
|
|
45
|
+
name='orient_x',
|
|
46
|
+
field=models.FloatField(),
|
|
47
|
+
),
|
|
48
|
+
migrations.AlterField(
|
|
49
|
+
model_name='sensorassignment',
|
|
50
|
+
name='orient_y',
|
|
51
|
+
field=models.FloatField(),
|
|
52
|
+
),
|
|
53
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated by Django 5.1.2 on 2025-04-28 02:26
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('apps_prediction', '0005_remove_sensorassignment_offset_x_and_more'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.RemoveField(
|
|
14
|
+
model_name='sensorassignment',
|
|
15
|
+
name='show_x',
|
|
16
|
+
),
|
|
17
|
+
migrations.RemoveField(
|
|
18
|
+
model_name='sensorassignment',
|
|
19
|
+
name='show_y',
|
|
20
|
+
),
|
|
21
|
+
migrations.RemoveField(
|
|
22
|
+
model_name='sensorassignment',
|
|
23
|
+
name='show_z',
|
|
24
|
+
),
|
|
25
|
+
]
|
irie/apps/prediction/models.py
CHANGED
|
@@ -5,15 +5,14 @@
|
|
|
5
5
|
#===----------------------------------------------------------------------===#
|
|
6
6
|
from django.db import models
|
|
7
7
|
|
|
8
|
-
from irie.apps.inventory.models import Asset
|
|
8
|
+
from irie.apps.inventory.models import Asset, Sensor
|
|
9
|
+
|
|
9
10
|
|
|
10
11
|
class PredictorModel(models.Model):
|
|
11
12
|
# https://docs.djangoproject.com/en/4.2/ref/models/fields/
|
|
12
13
|
class Protocol(models.TextChoices):
|
|
13
14
|
TYPE1 = "IRIE_PREDICTOR_V1"
|
|
14
15
|
TYPE2 = "IRIE_PREDICTOR_T2"
|
|
15
|
-
# TYPE3 = "IRIE_PREDICTOR_T3"
|
|
16
|
-
# TYPE4 = "IRIE_PREDICTOR_T4"
|
|
17
16
|
|
|
18
17
|
id = models.BigAutoField(primary_key=True)
|
|
19
18
|
name = models.CharField(max_length=35)
|
|
@@ -36,6 +35,26 @@ class PredictorModel(models.Model):
|
|
|
36
35
|
return f"{self.asset.calid} - {self.name} : {self.description}"
|
|
37
36
|
|
|
38
37
|
|
|
38
|
+
class SensorAssignment(models.Model):
|
|
39
|
+
predictor = models.ForeignKey(PredictorModel, on_delete=models.CASCADE)
|
|
40
|
+
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE)
|
|
41
|
+
node = models.IntegerField()
|
|
42
|
+
role = models.CharField(
|
|
43
|
+
max_length=16,
|
|
44
|
+
choices=[
|
|
45
|
+
('input', 'Input'),
|
|
46
|
+
('output', 'Output'),
|
|
47
|
+
]
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
orient_z = models.FloatField()
|
|
51
|
+
orient_x = models.FloatField()
|
|
52
|
+
orient_y = models.FloatField()
|
|
53
|
+
# show_x = models.FloatField()
|
|
54
|
+
# show_y = models.FloatField()
|
|
55
|
+
# show_z = models.FloatField()
|
|
56
|
+
|
|
57
|
+
|
|
39
58
|
# class PhysicsPredictor(models.Model):
|
|
40
59
|
# class Units(models.TextChoices):
|
|
41
60
|
# iks = "IKS"
|
|
@@ -20,7 +20,8 @@ class Runner:
|
|
|
20
20
|
|
|
21
21
|
if isinstance(pred, dict):
|
|
22
22
|
# Create from dict when posted from API; this
|
|
23
|
-
# is used to create a new PredictorModel
|
|
23
|
+
# is used to create a new PredictorModel.
|
|
24
|
+
# In the future this may be removed.
|
|
24
25
|
self.name: str = pred["name"]
|
|
25
26
|
self.description = pred.get("description", "")
|
|
26
27
|
self.conf = pred["config"]
|
|
@@ -28,7 +29,7 @@ class Runner:
|
|
|
28
29
|
self.entry_point = pred["entry_point"]
|
|
29
30
|
self.active = pred.get("active", True)
|
|
30
31
|
else:
|
|
31
|
-
# Create from PredictorModel when loaded from database.
|
|
32
|
+
# Create from existing PredictorModel when loaded from database.
|
|
32
33
|
# This is done when running analysis
|
|
33
34
|
self.id = pred.id
|
|
34
35
|
self.asset = pred.asset
|
|
@@ -38,9 +39,18 @@ class Runner:
|
|
|
38
39
|
self.entry_point = pred.entry_point
|
|
39
40
|
self.metrics = pred.metrics
|
|
40
41
|
self.active = pred.active
|
|
42
|
+
|
|
43
|
+
# NEW:
|
|
44
|
+
self.predictor = pred
|
|
45
|
+
|
|
46
|
+
self.runs = {}
|
|
41
47
|
if pred.config_file:
|
|
42
|
-
|
|
48
|
+
# TODO: for Amazon S3
|
|
49
|
+
# self.model_file = Path(pred.config_file.path).resolve()
|
|
43
50
|
self.out_dir = Path(__file__).parents[0]/"Predictions"
|
|
51
|
+
else:
|
|
52
|
+
self.model_file = None
|
|
53
|
+
self.out_dir = None
|
|
44
54
|
self.runs = {}
|
|
45
55
|
|
|
46
56
|
@abstractmethod
|
|
@@ -47,7 +47,7 @@ def new_cd(x):
|
|
|
47
47
|
class OpenSeesRunner(Runner):
|
|
48
48
|
@property
|
|
49
49
|
def platform(self):
|
|
50
|
-
return self.conf.get("platform", "")
|
|
50
|
+
return self.conf.get("platform", "xara")
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
@classmethod
|
|
@@ -58,9 +58,7 @@ class OpenSeesRunner(Runner):
|
|
|
58
58
|
# TODO
|
|
59
59
|
data.pop("file")
|
|
60
60
|
uploaded_file = request.FILES.get('config_file', None)
|
|
61
|
-
print(uploaded_file)
|
|
62
61
|
if uploaded_file:
|
|
63
|
-
|
|
64
62
|
with open(uploaded_file.name, 'wb+') as destination:
|
|
65
63
|
for chunk in uploaded_file.chunks():
|
|
66
64
|
destination.write(chunk)
|
|
@@ -499,72 +497,126 @@ class OpenSeesRunner(Runner):
|
|
|
499
497
|
return {}
|
|
500
498
|
return {}
|
|
501
499
|
|
|
500
|
+
#
|
|
501
|
+
# Viewing methods
|
|
502
|
+
#
|
|
503
|
+
def structural_section(self, name):
|
|
504
|
+
from shps.shapes import from_aisc
|
|
505
|
+
from openbim.csi._frame.section import section_geometry, section_mesh
|
|
502
506
|
|
|
503
|
-
import
|
|
504
|
-
|
|
507
|
+
from openbim.csi import load, create_model, collect_outlines
|
|
508
|
+
# 1) Parse the CSI file
|
|
509
|
+
try:
|
|
510
|
+
csi_file = self.predictor.config_file
|
|
511
|
+
csi = load((str(line.decode()).replace("\r\n","\n") for line in csi_file.readlines()))
|
|
512
|
+
except:
|
|
513
|
+
return None
|
|
514
|
+
|
|
515
|
+
mesh = section_mesh(csi, name)
|
|
516
|
+
return {}, mesh
|
|
517
|
+
mesh = from_aisc("W12x14").create_mesh(mesh_kwds={"engine": "meshpy"})
|
|
518
|
+
mesh = (mesh.nodes, mesh.cells())
|
|
519
|
+
# return {}, mesh
|
|
520
|
+
|
|
505
521
|
|
|
506
|
-
class PredictorType1(Runner):
|
|
507
|
-
@property
|
|
508
|
-
def platform(self):
|
|
509
|
-
return self.conf.get("platform", "")
|
|
510
522
|
|
|
511
|
-
@classmethod
|
|
512
|
-
def create(cls, asset, request):
|
|
513
|
-
from irie.apps.prediction.models import PredictorModel
|
|
514
|
-
predictor = PredictorModel()
|
|
515
|
-
data = json.loads(request.data.get("json"))
|
|
516
|
-
predictor.entry_point = [
|
|
517
|
-
sys.executable, "-m", "opensees"
|
|
518
|
-
]
|
|
519
|
-
data["metrics"] = []
|
|
520
|
-
|
|
521
|
-
predictor.name = data.pop("name")
|
|
522
|
-
predictor.config = data
|
|
523
|
-
predictor.asset = asset
|
|
524
|
-
predictor.protocol = "IRIE_PREDICTOR_T1"
|
|
525
|
-
predictor.active = False
|
|
526
|
-
return predictor
|
|
527
523
|
|
|
524
|
+
def structural_members(self):
|
|
528
525
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
"
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
"
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
526
|
+
from openbim.csi import load, create_model, collect_outlines
|
|
527
|
+
# 1) Parse the CSI file
|
|
528
|
+
csi_file = self.predictor.config_file
|
|
529
|
+
try:
|
|
530
|
+
csi = load((str(line.decode()).replace("\r\n","\n") for line in csi_file.readlines()))
|
|
531
|
+
except Exception as e:
|
|
532
|
+
import sys
|
|
533
|
+
print(f"Error loading CSiBridge file: {e}", file=sys.stderr)
|
|
534
|
+
csi = {}
|
|
535
|
+
|
|
536
|
+
for item in csi.get("BRIDGE BENT DEFINITIONS 2 - COLUMN DATA",[]):
|
|
537
|
+
if "ColNum" in item and "Section" in item:
|
|
538
|
+
yield {
|
|
539
|
+
"name": item["ColNum"],
|
|
540
|
+
"type": "Column",
|
|
541
|
+
"section": item["Section"],
|
|
542
|
+
}
|
|
547
543
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
544
|
+
for item in csi.get("BRIDGE OBJECT DEFINITIONS 03 - SPANS 1 - GENERAL", []):
|
|
545
|
+
if "SpanName" in item and "BridgeSect" in item:
|
|
546
|
+
yield {
|
|
547
|
+
"name": item["SpanName"],
|
|
548
|
+
"type": "Span",
|
|
549
|
+
"section": None,
|
|
550
|
+
}
|
|
554
551
|
|
|
555
|
-
def runPrediction(self, run_id: RunID):
|
|
556
|
-
command = [*self.entry_point, "run", str(run_id)]
|
|
557
552
|
|
|
558
|
-
if "scale" in self.event.upload_data:
|
|
559
|
-
command.extend(["--scale", str(float(self.event.upload_data["scale"]))])
|
|
560
|
-
print(":: Running ", command, file=sys.stderr)
|
|
561
|
-
subprocess.check_output(command)
|
|
562
553
|
|
|
563
|
-
print(f":: Model {self.name} returned", file=sys.stderr)
|
|
564
|
-
return
|
|
565
554
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
555
|
+
# import subprocess
|
|
556
|
+
# class Event: pass
|
|
557
|
+
|
|
558
|
+
# class PredictorType1(Runner):
|
|
559
|
+
# @property
|
|
560
|
+
# def platform(self):
|
|
561
|
+
# return self.conf.get("platform", "")
|
|
562
|
+
|
|
563
|
+
# @classmethod
|
|
564
|
+
# def create(cls, asset, request):
|
|
565
|
+
# from irie.apps.prediction.models import PredictorModel
|
|
566
|
+
# predictor = PredictorModel()
|
|
567
|
+
# data = json.loads(request.data.get("json"))
|
|
568
|
+
# predictor.entry_point = [
|
|
569
|
+
# sys.executable, "-m", "opensees"
|
|
570
|
+
# ]
|
|
571
|
+
# data["metrics"] = []
|
|
572
|
+
|
|
573
|
+
# predictor.name = data.pop("name")
|
|
574
|
+
# predictor.config = data
|
|
575
|
+
# predictor.asset = asset
|
|
576
|
+
# predictor.protocol = "IRIE_PREDICTOR_T1"
|
|
577
|
+
# predictor.active = False
|
|
578
|
+
# return predictor
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
# @classproperty
|
|
582
|
+
# def schema(cls):
|
|
583
|
+
# from irie.apps.prediction.runners.opensees import schemas
|
|
584
|
+
# return {
|
|
585
|
+
# "title": "Structural Model",
|
|
586
|
+
# "options": {"disable_collaps": True},
|
|
587
|
+
# "schema": "http://json-schema.org/draft-04/schema#",
|
|
588
|
+
# "type": "object",
|
|
589
|
+
# "properties": {
|
|
590
|
+
# "platform": {
|
|
591
|
+
# "type": "string",
|
|
592
|
+
# "title": "Platform",
|
|
593
|
+
# "enum": ["OpenSees","CSiBridge"]
|
|
594
|
+
# },
|
|
595
|
+
# "model": schemas.load("hwd_conf.schema.json"),
|
|
596
|
+
# "analysis": schemas.load("hwd_analysis.schema.json"),
|
|
597
|
+
# }
|
|
598
|
+
# }
|
|
599
|
+
|
|
600
|
+
# def newPrediction(self, event: Event) -> RunID:
|
|
601
|
+
# self.event = event
|
|
602
|
+
# event_file = Path(event.event_file.path).resolve()
|
|
603
|
+
# command = [*self.entry_point, "new", event_file]
|
|
604
|
+
# run_id = subprocess.check_output(command).decode().strip()
|
|
605
|
+
# return RunID(int(run_id))
|
|
606
|
+
|
|
607
|
+
# def runPrediction(self, run_id: RunID):
|
|
608
|
+
# command = [*self.entry_point, "run", str(run_id)]
|
|
609
|
+
|
|
610
|
+
# if "scale" in self.event.upload_data:
|
|
611
|
+
# command.extend(["--scale", str(float(self.event.upload_data["scale"]))])
|
|
612
|
+
# print(":: Running ", command, file=sys.stderr)
|
|
613
|
+
# subprocess.check_output(command)
|
|
614
|
+
|
|
615
|
+
# print(f":: Model {self.name} returned", file=sys.stderr)
|
|
616
|
+
# return
|
|
617
|
+
|
|
618
|
+
# def getMetricData(self, run, metric):
|
|
619
|
+
# try:
|
|
620
|
+
# return json.loads(subprocess.check_output([*self.entry_point, "get", str(run), metric]).decode())
|
|
621
|
+
# except json.decoder.JSONDecodeError:
|
|
622
|
+
# return {}
|
|
@@ -13,20 +13,11 @@ import io
|
|
|
13
13
|
import base64
|
|
14
14
|
import numpy as np
|
|
15
15
|
# Ensure Agg backend is set for non-interactive plotting
|
|
16
|
-
|
|
17
|
-
matplotlib.use('Agg')
|
|
18
|
-
from matplotlib import pyplot as plt, ticker, cm
|
|
16
|
+
|
|
19
17
|
import quakeio
|
|
20
|
-
from mdof import transform
|
|
21
18
|
from scipy.signal import find_peaks
|
|
22
|
-
from mdof.utilities import Config, extract_channels
|
|
23
|
-
from matplotlib import colormaps
|
|
24
19
|
import subprocess
|
|
25
|
-
|
|
26
|
-
# import scienceplots
|
|
27
|
-
# plt.style.use(["science"])
|
|
28
|
-
# except ImportError:
|
|
29
|
-
# pass
|
|
20
|
+
|
|
30
21
|
|
|
31
22
|
N_PEAKS = 5 # number of "significant" peaks per record
|
|
32
23
|
MISSING_CHANNEL_LIMIT = 3 # number of missing output channels allowed before skipping event
|
|
@@ -325,6 +316,7 @@ def _load_events(asset, output_channels):
|
|
|
325
316
|
}
|
|
326
317
|
"""
|
|
327
318
|
events = {}
|
|
319
|
+
from mdof.utilities import extract_channels
|
|
328
320
|
for evt in EventRecord.objects.filter(asset=asset):
|
|
329
321
|
|
|
330
322
|
try:
|
|
@@ -349,6 +341,8 @@ def _get_spectra(event, conf, cmap):
|
|
|
349
341
|
with the maximum period of the N_PEAKS tallest peaks, as well as plotting options
|
|
350
342
|
such as color and alpha.
|
|
351
343
|
"""
|
|
344
|
+
from mdof import transform
|
|
345
|
+
from mdof.utilities import Config
|
|
352
346
|
period_band = conf.period_band
|
|
353
347
|
|
|
354
348
|
n_outputs = event['outputs'].shape[0]
|
|
@@ -439,6 +433,10 @@ def plot_spectral_surface(ax, traces, **options):
|
|
|
439
433
|
|
|
440
434
|
|
|
441
435
|
def _plot_mountains(spectra, accellim=None):
|
|
436
|
+
import matplotlib
|
|
437
|
+
matplotlib.use('Agg')
|
|
438
|
+
from matplotlib import pyplot as plt, ticker, cm
|
|
439
|
+
from matplotlib import colormaps
|
|
442
440
|
fig = plt.figure(figsize=(13,13))
|
|
443
441
|
ax = fig.add_subplot(projection='3d')
|
|
444
442
|
|
|
@@ -469,7 +467,7 @@ def _plot_mountains(spectra, accellim=None):
|
|
|
469
467
|
|
|
470
468
|
|
|
471
469
|
def make_mountains(asset, conf=None, output_channels=None):
|
|
472
|
-
|
|
470
|
+
from mdof.utilities import Config
|
|
473
471
|
cmap = colormaps['plasma']
|
|
474
472
|
if conf is None:
|
|
475
473
|
conf = Config()
|
|
@@ -512,7 +510,6 @@ def make_mountains(asset, conf=None, output_channels=None):
|
|
|
512
510
|
buffer = io.BytesIO()
|
|
513
511
|
fig.savefig(buffer, format="png")
|
|
514
512
|
buffer.seek(0)
|
|
515
|
-
# plt.show()
|
|
516
513
|
|
|
517
514
|
# Encode the image as Base64
|
|
518
515
|
return base64.b64encode(buffer.read()).decode("utf-8")
|
|
@@ -549,6 +546,10 @@ def parse_args(args):
|
|
|
549
546
|
if __name__ == '__main__':
|
|
550
547
|
|
|
551
548
|
import sys
|
|
549
|
+
from matplotlib import pyplot as plt, ticker, cm
|
|
550
|
+
from matplotlib import colormaps
|
|
551
|
+
from mdof.utilities import Config
|
|
552
|
+
|
|
552
553
|
procedure = parse_args(sys.argv)
|
|
553
554
|
STATION_TYPE = procedure['STATION_TYPE']
|
|
554
555
|
outdir = Path(procedure['outdir'])
|
irie/apps/prediction/urls.py
CHANGED
|
@@ -8,13 +8,18 @@
|
|
|
8
8
|
#
|
|
9
9
|
#----------------------------------------------------------------------------#
|
|
10
10
|
from django.urls import re_path
|
|
11
|
-
from .views import
|
|
11
|
+
from .views import (
|
|
12
|
+
asset_predictors, predictor_profile, predictor_profile_detail,
|
|
13
|
+
create_mdof, create_model, asset_map
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
_ROOT = "^inventory/(?P<calid>[0-9 A-Z-]*)/predictors"
|
|
12
17
|
|
|
13
18
|
urlpatterns = [
|
|
14
|
-
re_path("
|
|
15
|
-
re_path("
|
|
16
|
-
re_path("
|
|
17
|
-
re_path("
|
|
18
|
-
re_path("
|
|
19
|
-
re_path("
|
|
19
|
+
re_path(f"{_ROOT}/(?P<preid>[0-9]{{1,}})/$", predictor_profile),
|
|
20
|
+
re_path(f"{_ROOT}/(?P<preid>[0-9]{{1,}})/detail/", predictor_profile_detail),
|
|
21
|
+
re_path(f"{_ROOT}/create/map/$", asset_map),
|
|
22
|
+
re_path(f"{_ROOT}/create/model/$", create_model),
|
|
23
|
+
re_path(f"{_ROOT}/create/v1/$", create_mdof),
|
|
24
|
+
re_path(f"{_ROOT}/$", asset_predictors, name="asset_predictors")
|
|
20
25
|
]
|