irie 0.0.0__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/__main__.py +24 -0
- irie/apps/__init__.py +5 -0
- irie/apps/authentication/__init__.py +1 -0
- irie/apps/authentication/admin.py +1 -0
- irie/apps/authentication/config.py +6 -0
- irie/apps/authentication/forms.py +41 -0
- irie/apps/authentication/migrations/__init__.py +1 -0
- irie/apps/authentication/models.py +1 -0
- irie/apps/authentication/tests.py +1 -0
- irie/apps/authentication/urls.py +9 -0
- irie/apps/authentication/views.py +53 -0
- irie/apps/config.py +8 -0
- irie/apps/context_processors.py +5 -0
- irie/apps/documents/__init__.py +0 -0
- irie/apps/documents/apps.py +7 -0
- irie/apps/documents/documents.py +61 -0
- irie/apps/documents/migrations/__init__.py +0 -0
- irie/apps/documents/tests.py +3 -0
- irie/apps/documents/urls.py +12 -0
- irie/apps/documents/views.py +27 -0
- irie/apps/evaluation/__init__.py +0 -0
- irie/apps/evaluation/admin.py +43 -0
- irie/apps/evaluation/apps.py +18 -0
- irie/apps/evaluation/daemon.py +107 -0
- irie/apps/evaluation/identification.py +196 -0
- irie/apps/evaluation/migrations/0001_initial.py +25 -0
- irie/apps/evaluation/migrations/0002_remove_evaluation_cesmd.py +17 -0
- irie/apps/evaluation/migrations/0003_evaluation_asset.py +20 -0
- irie/apps/evaluation/migrations/__init__.py +0 -0
- irie/apps/evaluation/models.py +72 -0
- irie/apps/evaluation/urls.py +16 -0
- irie/apps/evaluation/views.py +68 -0
- irie/apps/events/__init__.py +0 -0
- irie/apps/events/admin.py +9 -0
- irie/apps/events/apps.py +12 -0
- irie/apps/events/migrations/0001_initial.py +27 -0
- irie/apps/events/migrations/0002_alter_event_id.py +18 -0
- irie/apps/events/migrations/0003_event_cesmd.py +19 -0
- irie/apps/events/migrations/0004_event_record_identifier.py +19 -0
- irie/apps/events/migrations/0005_event_asset.py +21 -0
- irie/apps/events/migrations/0006_alter_event_event_file.py +18 -0
- irie/apps/events/migrations/__init__.py +0 -0
- irie/apps/events/models.py +70 -0
- irie/apps/events/tests.py +1 -0
- irie/apps/events/tests_events.py +240 -0
- irie/apps/events/urls.py +29 -0
- irie/apps/events/views.py +55 -0
- irie/apps/events/views_events.py +215 -0
- irie/apps/inventory/CESMD.py +81 -0
- irie/apps/inventory/__init__.py +5 -0
- irie/apps/inventory/admin.py +10 -0
- irie/apps/inventory/apps.py +12 -0
- irie/apps/inventory/archive/arcGIS.py +1175 -0
- irie/apps/inventory/calid.py +65 -0
- irie/apps/inventory/fields.py +5 -0
- irie/apps/inventory/forms.py +12 -0
- irie/apps/inventory/migrations/0001_initial.py +31 -0
- irie/apps/inventory/migrations/0002_assetevaluationmodel_cesmd.py +19 -0
- irie/apps/inventory/migrations/0003_auto_20230520_2030.py +23 -0
- irie/apps/inventory/migrations/0004_asset.py +27 -0
- irie/apps/inventory/migrations/0005_auto_20230731_1802.py +23 -0
- irie/apps/inventory/migrations/0006_auto_20230731_1816.py +28 -0
- irie/apps/inventory/migrations/0007_auto_20230731_1827.py +24 -0
- irie/apps/inventory/migrations/0008_asset_is_complete.py +19 -0
- irie/apps/inventory/migrations/0009_auto_20230731_1842.py +29 -0
- irie/apps/inventory/migrations/0010_auto_20230801_0025.py +23 -0
- irie/apps/inventory/migrations/0011_alter_asset_cgs_data.py +18 -0
- irie/apps/inventory/migrations/0012_corridor.py +22 -0
- irie/apps/inventory/migrations/0013_alter_asset_cesmd.py +18 -0
- irie/apps/inventory/migrations/0014_alter_asset_cesmd.py +18 -0
- irie/apps/inventory/migrations/__init__.py +0 -0
- irie/apps/inventory/models.py +70 -0
- irie/apps/inventory/tables.py +584 -0
- irie/apps/inventory/traffic.py +175052 -0
- irie/apps/inventory/urls.py +25 -0
- irie/apps/inventory/views.py +515 -0
- irie/apps/management/__init__.py +0 -0
- irie/apps/management/commands/__init__.py +0 -0
- irie/apps/networks/__init__.py +0 -0
- irie/apps/networks/apps.py +5 -0
- irie/apps/networks/forms.py +64 -0
- irie/apps/networks/migrations/0001_initial.py +26 -0
- irie/apps/networks/migrations/__init__.py +0 -0
- irie/apps/networks/models.py +14 -0
- irie/apps/networks/networks.py +782 -0
- irie/apps/networks/tests.py +1 -0
- irie/apps/networks/urls.py +18 -0
- irie/apps/networks/views.py +89 -0
- irie/apps/prediction/__init__.py +0 -0
- irie/apps/prediction/admin.py +9 -0
- irie/apps/prediction/apps.py +12 -0
- irie/apps/prediction/forms.py +20 -0
- irie/apps/prediction/metrics.py +61 -0
- irie/apps/prediction/migrations/0001_initial.py +32 -0
- irie/apps/prediction/migrations/0002_auto_20230731_1801.py +27 -0
- irie/apps/prediction/migrations/0003_rename_assetevaluationmodel_evaluation.py +18 -0
- irie/apps/prediction/migrations/0004_delete_evaluation.py +16 -0
- irie/apps/prediction/migrations/0005_predictormodel_protocol.py +18 -0
- irie/apps/prediction/migrations/0006_alter_predictormodel_protocol.py +18 -0
- irie/apps/prediction/migrations/0007_predictormodel_active.py +19 -0
- irie/apps/prediction/migrations/0008_predictormodel_description.py +18 -0
- irie/apps/prediction/migrations/0009_predictormodel_entry_point.py +19 -0
- irie/apps/prediction/migrations/0010_alter_predictormodel_entry_point.py +18 -0
- irie/apps/prediction/migrations/0011_remove_predictormodel_entry_point.py +17 -0
- irie/apps/prediction/migrations/0012_predictormodel_entry_point.py +18 -0
- irie/apps/prediction/migrations/0013_predictormodel_metrics.py +18 -0
- irie/apps/prediction/migrations/0014_auto_20240930_0004.py +28 -0
- irie/apps/prediction/migrations/0015_alter_predictormodel_render_file.py +18 -0
- irie/apps/prediction/migrations/__init__.py +0 -0
- irie/apps/prediction/models.py +37 -0
- irie/apps/prediction/predictor.py +286 -0
- irie/apps/prediction/runners/__init__.py +450 -0
- irie/apps/prediction/runners/metrics.py +168 -0
- irie/apps/prediction/runners/opensees/__init__.py +0 -0
- irie/apps/prediction/runners/opensees/schemas/__init__.py +39 -0
- irie/apps/prediction/runners/utilities.py +277 -0
- irie/apps/prediction/runners/xmlutils.py +232 -0
- irie/apps/prediction/runners/zipped.py +27 -0
- irie/apps/prediction/templatetags/__init__.py +0 -0
- irie/apps/prediction/templatetags/predictor.py +20 -0
- irie/apps/prediction/urls.py +19 -0
- irie/apps/prediction/views.py +184 -0
- irie/apps/prediction/views_api.py +216 -0
- irie/apps/site/__init__.py +0 -0
- irie/apps/site/admin.py +1 -0
- irie/apps/site/config.py +6 -0
- irie/apps/site/migrations/__init__.py +1 -0
- irie/apps/site/models.py +2 -0
- irie/apps/site/templatetags/__init__.py +0 -0
- irie/apps/site/templatetags/indexing.py +7 -0
- irie/apps/site/tests.py +1 -0
- irie/apps/site/urls.py +8 -0
- irie/apps/site/view_sdof.py +40 -0
- irie/apps/site/view_utils.py +13 -0
- irie/apps/site/views.py +88 -0
- irie/core/__init__.py +5 -0
- irie/core/asgi.py +12 -0
- irie/core/settings.py +223 -0
- irie/core/urls.py +39 -0
- irie/core/wsgi.py +12 -0
- irie-0.0.0.dist-info/METADATA +48 -0
- irie-0.0.0.dist-info/RECORD +145 -0
- irie-0.0.0.dist-info/WHEEL +5 -0
- irie-0.0.0.dist-info/entry_points.txt +2 -0
- irie-0.0.0.dist-info/top_level.txt +1 -0
irie/__main__.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
#===----------------------------------------------------------------------===#
|
|
3
|
+
#
|
|
4
|
+
# STAIRLab -- STructural Artificial Intelligence Laboratory
|
|
5
|
+
#
|
|
6
|
+
#===----------------------------------------------------------------------===#
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
def main():
|
|
12
|
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
|
|
13
|
+
try:
|
|
14
|
+
from django.core.management import execute_from_command_line
|
|
15
|
+
except ImportError as exc:
|
|
16
|
+
raise ImportError(
|
|
17
|
+
"Couldn't import Django. Are you sure it's installed and "
|
|
18
|
+
"available on your PYTHONPATH environment variable? Did you "
|
|
19
|
+
"forget to activate a virtual environment?"
|
|
20
|
+
) from exc
|
|
21
|
+
execute_from_command_line(sys.argv)
|
|
22
|
+
|
|
23
|
+
if __name__ == '__main__':
|
|
24
|
+
main()
|
irie/apps/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from django.contrib import admin
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from django import forms
|
|
2
|
+
from django.contrib.auth.forms import UserCreationForm
|
|
3
|
+
from django.contrib.auth.models import User
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LoginForm(forms.Form):
|
|
7
|
+
username = forms.CharField(
|
|
8
|
+
widget=forms.TextInput(
|
|
9
|
+
attrs={"placeholder": "Username", "class": "form-control"}
|
|
10
|
+
)
|
|
11
|
+
)
|
|
12
|
+
password = forms.CharField(
|
|
13
|
+
widget=forms.PasswordInput(
|
|
14
|
+
attrs={"placeholder": "Password", "class": "form-control"}
|
|
15
|
+
)
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SignUpForm(UserCreationForm):
|
|
20
|
+
username = forms.CharField(
|
|
21
|
+
widget=forms.TextInput(
|
|
22
|
+
attrs={"placeholder": "Username", "class": "form-control"}
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
email = forms.EmailField(
|
|
26
|
+
widget=forms.EmailInput(attrs={"placeholder": "Email", "class": "form-control"})
|
|
27
|
+
)
|
|
28
|
+
password1 = forms.CharField(
|
|
29
|
+
widget=forms.PasswordInput(
|
|
30
|
+
attrs={"placeholder": "Password", "class": "form-control"}
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
password2 = forms.CharField(
|
|
34
|
+
widget=forms.PasswordInput(
|
|
35
|
+
attrs={"placeholder": "Password check", "class": "form-control"}
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
class Meta:
|
|
40
|
+
model = User
|
|
41
|
+
fields = ("username", "email", "password1", "password2")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from django.db import models
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from django.test import TestCase
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from django.urls import path
|
|
2
|
+
from .views import login_view, register_user
|
|
3
|
+
from django.contrib.auth.views import LogoutView
|
|
4
|
+
|
|
5
|
+
urlpatterns = [
|
|
6
|
+
path("login/", login_view, name="login"),
|
|
7
|
+
path("register/", register_user, name="register"),
|
|
8
|
+
path("logout/", LogoutView.as_view(), name="logout"),
|
|
9
|
+
]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from django.shortcuts import render, redirect
|
|
2
|
+
from django.contrib.auth import authenticate, login
|
|
3
|
+
from .forms import LoginForm, SignUpForm
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def login_view(request):
|
|
7
|
+
form = LoginForm(request.POST or None)
|
|
8
|
+
|
|
9
|
+
msg = None
|
|
10
|
+
|
|
11
|
+
if request.method == "POST":
|
|
12
|
+
if form.is_valid():
|
|
13
|
+
username = form.cleaned_data.get("username")
|
|
14
|
+
password = form.cleaned_data.get("password")
|
|
15
|
+
user = authenticate(username=username, password=password)
|
|
16
|
+
if user is not None:
|
|
17
|
+
login(request, user)
|
|
18
|
+
return redirect("/")
|
|
19
|
+
else:
|
|
20
|
+
msg = "Invalid credentials"
|
|
21
|
+
else:
|
|
22
|
+
msg = "Error validating the form"
|
|
23
|
+
|
|
24
|
+
return render(request, "accounts/login.html", {"form": form, "msg": msg})
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def register_user(request):
|
|
28
|
+
msg = None
|
|
29
|
+
success = False
|
|
30
|
+
|
|
31
|
+
if request.method == "POST":
|
|
32
|
+
form = SignUpForm(request.POST)
|
|
33
|
+
if form.is_valid():
|
|
34
|
+
form.save()
|
|
35
|
+
username = form.cleaned_data.get("username")
|
|
36
|
+
raw_password = form.cleaned_data.get("password1")
|
|
37
|
+
user = authenticate(username=username, password=raw_password)
|
|
38
|
+
|
|
39
|
+
msg = "User created successfully."
|
|
40
|
+
success = True
|
|
41
|
+
|
|
42
|
+
# return redirect("/login/")
|
|
43
|
+
|
|
44
|
+
else:
|
|
45
|
+
msg = "Form is not valid"
|
|
46
|
+
else:
|
|
47
|
+
form = SignUpForm()
|
|
48
|
+
|
|
49
|
+
return render(
|
|
50
|
+
request,
|
|
51
|
+
"accounts/register.html",
|
|
52
|
+
{"form": form, "msg": msg, "success": success},
|
|
53
|
+
)
|
irie/apps/config.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
TECHNOLOGY, MODELING, RESEARCH = range(3)
|
|
2
|
+
|
|
3
|
+
DOCUMENTS = [
|
|
4
|
+
# {
|
|
5
|
+
# "path": "2023-05-30 2nd Annual Report/BRACE2_2023_Annual_Report_Revised_After_Caltrans_Review.pdf",
|
|
6
|
+
# "title": "2nd Annual Report",
|
|
7
|
+
# "date": "2023-09-07",
|
|
8
|
+
# "scope": [TECHNOLOGY, MODELING, RESEARCH],
|
|
9
|
+
# "draft": False,
|
|
10
|
+
# "flags": ["new"]
|
|
11
|
+
# },
|
|
12
|
+
# {
|
|
13
|
+
# "path": "2023-05-30 2nd Annual Report/BRACE2_2023_Annual_Report.pdf",
|
|
14
|
+
# "title": "2nd Annual Report",
|
|
15
|
+
# "date": "2023-05-30",
|
|
16
|
+
# "scope": [TECHNOLOGY, MODELING, RESEARCH],
|
|
17
|
+
# "draft": True
|
|
18
|
+
# },
|
|
19
|
+
# {
|
|
20
|
+
# "path": "2021-10-27 ANNUAL Progress Report/BRACE2-Annual-Report-10-27-2021.pdf",
|
|
21
|
+
# "title": "1st Annual Report",
|
|
22
|
+
# "scope": [TECHNOLOGY, MODELING, RESEARCH],
|
|
23
|
+
# "date": "2021-10-27"
|
|
24
|
+
# },
|
|
25
|
+
# {
|
|
26
|
+
# "path": "2022-01-18 Progress Report 4/Update_BRACE2_1_18_2022.pdf",
|
|
27
|
+
# "title": "Progress Report 4",
|
|
28
|
+
# "scope": [MODELING, RESEARCH],
|
|
29
|
+
# "date": "2022-01-18"
|
|
30
|
+
# },
|
|
31
|
+
# {
|
|
32
|
+
# "path": "2022-04-21 Progress Report 5/BRACE2_Progress_Report_V_Part_I-4-21-2022.pdf",
|
|
33
|
+
# "title": "Progress Report 5",
|
|
34
|
+
# "scope": [MODELING, RESEARCH],
|
|
35
|
+
# "date": "2022-04-21"
|
|
36
|
+
# },
|
|
37
|
+
# {
|
|
38
|
+
# "path": "2022-06-01 NCE/BRACE2_Project_Extension_Workplan-6-1-2022.pdf",
|
|
39
|
+
# "title": "NCE/Project Extension Workplan",
|
|
40
|
+
# "scope": [MODELING, RESEARCH],
|
|
41
|
+
# "date": "2022-06-01"
|
|
42
|
+
# },
|
|
43
|
+
# {
|
|
44
|
+
# "path": "2022-08-11 Progress Report 6/BRACE2_Progress_Report_VI.pdf",
|
|
45
|
+
# "title": "Progress Report 6",
|
|
46
|
+
# "scope": [MODELING, RESEARCH],
|
|
47
|
+
# "date": "2022-08-11"
|
|
48
|
+
# },
|
|
49
|
+
# {
|
|
50
|
+
# "path": "2022-12-06 Memo Platform Guide/BRACE2_Memo_Platform_Guide_Final.pdf",
|
|
51
|
+
# "title": "Memo - Platform Guide",
|
|
52
|
+
# "scope": [MODELING],
|
|
53
|
+
# "date": "2022-12-06"
|
|
54
|
+
# },
|
|
55
|
+
# {
|
|
56
|
+
# "path": "2023-01-30 Platform Comment Responses/BRACE2_Memo_Platform_Comments_2-Jan-30-2023.pdf",
|
|
57
|
+
# "title": "Memo - Platform Comment Responses",
|
|
58
|
+
# "date": "2023-01-30"
|
|
59
|
+
# }
|
|
60
|
+
]
|
|
61
|
+
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from django.urls import path
|
|
2
|
+
from django.conf.urls.static import static
|
|
3
|
+
from core import settings
|
|
4
|
+
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
|
5
|
+
|
|
6
|
+
from . import views
|
|
7
|
+
|
|
8
|
+
urlpatterns = [
|
|
9
|
+
path("documents/", views.document_list, name="documents"),
|
|
10
|
+
path("documents.html", views.document_list),
|
|
11
|
+
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
|
12
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from django.shortcuts import render
|
|
2
|
+
|
|
3
|
+
from django import template
|
|
4
|
+
from django.contrib.auth.decorators import login_required
|
|
5
|
+
from django.http import HttpResponse, HttpResponseRedirect
|
|
6
|
+
from django.template import loader
|
|
7
|
+
|
|
8
|
+
from .documents import DOCUMENTS
|
|
9
|
+
|
|
10
|
+
@login_required(login_url="/login/")
|
|
11
|
+
def document_list(request):
|
|
12
|
+
|
|
13
|
+
context = {}
|
|
14
|
+
load_template = "documents.html"
|
|
15
|
+
context["documents"] = sorted(DOCUMENTS, key=lambda i: i["date"], reverse=True)
|
|
16
|
+
context["segment"] = load_template
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
html_template = loader.get_template("documents/" + load_template)
|
|
20
|
+
return HttpResponse(html_template.render(context, request))
|
|
21
|
+
|
|
22
|
+
except Exception as e:
|
|
23
|
+
if "DEBUG" in os.environ and os.environ["DEBUG"]:
|
|
24
|
+
raise e
|
|
25
|
+
html_template = loader.get_template("home/page-500.html")
|
|
26
|
+
return HttpResponse(html_template.render(context, request))
|
|
27
|
+
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#===----------------------------------------------------------------------===#
|
|
2
|
+
#
|
|
3
|
+
# STAIRLab -- STructural Artificial Intelligence Laboratory
|
|
4
|
+
#
|
|
5
|
+
#===----------------------------------------------------------------------===#
|
|
6
|
+
#
|
|
7
|
+
# Summer 2023, BRACE2 Team
|
|
8
|
+
# Berkeley, CA
|
|
9
|
+
#
|
|
10
|
+
#----------------------------------------------------------------------------#
|
|
11
|
+
import json
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
from django.db.models import JSONField
|
|
15
|
+
from django.contrib import admin
|
|
16
|
+
from django.forms import widgets
|
|
17
|
+
|
|
18
|
+
from .models import Evaluation
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PrettyJSONWidget(widgets.Textarea):
|
|
24
|
+
|
|
25
|
+
def format_value(self, value):
|
|
26
|
+
try:
|
|
27
|
+
value = json.dumps(json.loads(value), indent=2, sort_keys=True)
|
|
28
|
+
# these lines will try to adjust size of TextArea to fit to content
|
|
29
|
+
row_lengths = [len(r) for r in value.split('\n')]
|
|
30
|
+
self.attrs['rows'] = min(max(len(row_lengths) + 2, 10), 30)
|
|
31
|
+
self.attrs['cols'] = min(max(max(row_lengths) + 2, 40), 120)
|
|
32
|
+
return value
|
|
33
|
+
except Exception as e:
|
|
34
|
+
logger.warning("Error while formatting JSON: {}".format(e))
|
|
35
|
+
return super(PrettyJSONWidget, self).format_value(value)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class JsonAdmin(admin.ModelAdmin):
|
|
39
|
+
formfield_overrides = {
|
|
40
|
+
JSONField: {'widget': PrettyJSONWidget}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
admin.site.register(Evaluation, JsonAdmin)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#===----------------------------------------------------------------------===#
|
|
2
|
+
#
|
|
3
|
+
# STAIRLab -- STructural Artificial Intelligence Laboratory
|
|
4
|
+
#
|
|
5
|
+
#===----------------------------------------------------------------------===#
|
|
6
|
+
#
|
|
7
|
+
# Summer 2023, BRACE2 Team
|
|
8
|
+
# Berkeley, CA
|
|
9
|
+
#
|
|
10
|
+
#----------------------------------------------------------------------------#
|
|
11
|
+
from django.apps import AppConfig
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class PredictionConfig(AppConfig):
|
|
15
|
+
default_auto_field = 'django.db.models.BigAutoField'
|
|
16
|
+
name = 'apps.evaluation'
|
|
17
|
+
label = 'apps_evaluation'
|
|
18
|
+
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#===----------------------------------------------------------------------===#
|
|
2
|
+
#
|
|
3
|
+
# STAIRLab -- STructural Artificial Intelligence Laboratory
|
|
4
|
+
#
|
|
5
|
+
#===----------------------------------------------------------------------===#
|
|
6
|
+
#
|
|
7
|
+
# Summer 2023, BRACE2 Team
|
|
8
|
+
# Berkeley, CA
|
|
9
|
+
#
|
|
10
|
+
#----------------------------------------------------------------------------#
|
|
11
|
+
import sys
|
|
12
|
+
import multiprocessing.dummy
|
|
13
|
+
from collections import defaultdict
|
|
14
|
+
from typing import List, Iterator, Tuple, Dict, Collection
|
|
15
|
+
|
|
16
|
+
from apps.prediction.predictor import RunID
|
|
17
|
+
from apps.prediction.metrics import HealthMetric, METRIC_CLASSES
|
|
18
|
+
|
|
19
|
+
class LiveEvaluation:
|
|
20
|
+
# TODO: Merge into models.Evaluation?
|
|
21
|
+
def __init__(self, event, predictors, evaluation):
|
|
22
|
+
self.predictors = predictors
|
|
23
|
+
|
|
24
|
+
self.metrics: Dict[str, Dict[str, HealthMetric]] = defaultdict(dict)
|
|
25
|
+
self.active_metrics: List[str] = list(METRIC_CLASSES.keys())
|
|
26
|
+
|
|
27
|
+
self._evaluation = evaluation
|
|
28
|
+
|
|
29
|
+
self.evaluation_data = defaultdict(lambda: {
|
|
30
|
+
"predictors": [],
|
|
31
|
+
"summary": {},
|
|
32
|
+
"details": {}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
def update(self):
|
|
36
|
+
self._evaluation.evaluation_data = dict(self.evaluation_data)
|
|
37
|
+
self.save(["evaluation_data"])
|
|
38
|
+
|
|
39
|
+
def save(self, fields=None):
|
|
40
|
+
if fields is None:
|
|
41
|
+
self._evaluation.save()
|
|
42
|
+
else:
|
|
43
|
+
self._evaluation.save(update_fields=fields)
|
|
44
|
+
|
|
45
|
+
def runPredictor(self, args: Tuple[str, Tuple[RunID, List[HealthMetric]]]):
|
|
46
|
+
predictor_name, (run_id, metrics) = args
|
|
47
|
+
self.predictors[predictor_name].runPrediction(run_id)
|
|
48
|
+
return predictor_name, run_id
|
|
49
|
+
|
|
50
|
+
# met_tag, predictor_name
|
|
51
|
+
def addMetric(self, mname: str, pid: str, confidence_score:int=0)->HealthMetric:
|
|
52
|
+
"""
|
|
53
|
+
mname: metric id
|
|
54
|
+
pid: predictor id
|
|
55
|
+
"""
|
|
56
|
+
#self.metrics[metric.metric_tag][metric.predictor] = metric
|
|
57
|
+
self.evaluation_data[mname]["predictors"].append(pid)
|
|
58
|
+
self.update()
|
|
59
|
+
return mname
|
|
60
|
+
|
|
61
|
+
def setMetricData(self, mname: str, pid: str, data: dict):
|
|
62
|
+
# self.metrics[mname][pid].data = data
|
|
63
|
+
# try:
|
|
64
|
+
# self.evaluation_data[mname]["details"][pid] = data["details"]
|
|
65
|
+
# except KeyError:
|
|
66
|
+
# self.evaluation_data[mname]["details"][pid] = data
|
|
67
|
+
# self.metrics[mname][pid].buildDetails()
|
|
68
|
+
# try:
|
|
69
|
+
# None
|
|
70
|
+
# except KeyError:
|
|
71
|
+
# self.evaluation_data[mname]["summary"][pid] = \
|
|
72
|
+
# self.metrics[mname][pid].getSummary()
|
|
73
|
+
|
|
74
|
+
self.evaluation_data[mname]["details"][pid] = data.get("details", data)
|
|
75
|
+
self.evaluation_data[mname]["summary"][pid] = data.get("summary", data)
|
|
76
|
+
if len(self.evaluation_data[mname]["summary"]) == 1:
|
|
77
|
+
self.evaluation_data[mname]["summary"][pid]["is_primary"] = True
|
|
78
|
+
|
|
79
|
+
self.update()
|
|
80
|
+
|
|
81
|
+
def assignMetricPredictors(self, event)->Dict[str, Tuple[RunID,List[HealthMetric]]]:
|
|
82
|
+
queued_predictions : Dict[str, Tuple[RunID,List[HealthMetric]]] = {}
|
|
83
|
+
|
|
84
|
+
for mname in self.active_metrics:
|
|
85
|
+
for predictor, score in self.scorePredictors(mname, self.predictors.values(), event):
|
|
86
|
+
print(predictor, score)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if predictor.name not in queued_predictions and predictor.active:
|
|
90
|
+
rid = predictor.newPrediction(event)
|
|
91
|
+
queued_predictions[predictor.name] = (rid, [])
|
|
92
|
+
|
|
93
|
+
predictor.activateMetric(mname, queued_predictions[predictor.name][0])
|
|
94
|
+
queued_predictions[predictor.name][1].append(
|
|
95
|
+
#self.addMetric(METRIC_CLASSES[metric](predictor.name), score)
|
|
96
|
+
self.addMetric(mname, predictor.name, score)
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return queued_predictions
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def scorePredictors(self, metric, predictors: Collection["Predictor"], event)->Iterator[Tuple["Predictor", int]]:
|
|
103
|
+
for predictor in predictors:
|
|
104
|
+
if predictor.active and metric in predictor.getMetricList():
|
|
105
|
+
print(">>> ", predictor.name, metric, file=sys.stderr)
|
|
106
|
+
yield (predictor, 0)
|
|
107
|
+
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#===----------------------------------------------------------------------===#
|
|
2
|
+
#
|
|
3
|
+
# STAIRLab -- STructural Artificial Intelligence Laboratory
|
|
4
|
+
#
|
|
5
|
+
#===----------------------------------------------------------------------===#
|
|
6
|
+
#
|
|
7
|
+
# Summer 2023, BRACE2 Team
|
|
8
|
+
# Berkeley, CA
|
|
9
|
+
#
|
|
10
|
+
#----------------------------------------------------------------------------#
|
|
11
|
+
"""
|
|
12
|
+
0. dd = {event_id: {idx01: mode01, idx02: mode02}} // with mode0? = {node: [*ndf]}
|
|
13
|
+
// or mode0? = [*ndf] ?
|
|
14
|
+
// mode = {"period", "idx", "shape"}
|
|
15
|
+
1. aa = {event_id: mode}
|
|
16
|
+
2. for event in aa:
|
|
17
|
+
bb[event] = 0.0
|
|
18
|
+
for other_event in aa:
|
|
19
|
+
if other_event != event :
|
|
20
|
+
if assoc(dd[event], dd[other_event])[event] == event:
|
|
21
|
+
bb[event] += 1/(len(aa)-1)
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
import os
|
|
25
|
+
import json
|
|
26
|
+
from collections import defaultdict
|
|
27
|
+
|
|
28
|
+
import numpy as np
|
|
29
|
+
from apps.events.models import Event
|
|
30
|
+
from apps.site.view_utils import raise404
|
|
31
|
+
from apps.inventory.models import Asset
|
|
32
|
+
|
|
33
|
+
def mkdd(asset, pid, key):
|
|
34
|
+
evaluations = list(reversed(sorted(Evaluation.objects.filter(asset=asset),
|
|
35
|
+
key=lambda x: x.event.motion_data["event_date"])))
|
|
36
|
+
return {
|
|
37
|
+
i_eval: {
|
|
38
|
+
idx: mode for idx,mode in \
|
|
39
|
+
enumerate(evaluation.evaluation_data["SPECTRAL_SHIFT_IDENTIFICATION"]["summary"][pid])
|
|
40
|
+
if key in mode and mode.get("emac", 1.0) > 0.5 and mode.get("mpc", 1.0) > 0.5
|
|
41
|
+
|
|
42
|
+
} for i_eval,evaluation in enumerate(evaluations)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
def _ssid_stats(asset, pid, key):
|
|
46
|
+
filtered_modes = mkdd(asset, pid, key)
|
|
47
|
+
values = [mode[key] for mode in event.values() for event in filtered_modes.values()]
|
|
48
|
+
|
|
49
|
+
mean = np.mean(values)
|
|
50
|
+
std = np.std(values)
|
|
51
|
+
|
|
52
|
+
result = {}
|
|
53
|
+
for i_eval, event_results in filtered_modes.items():
|
|
54
|
+
idx = np.argmin(np.abs(mean - np.array([mode[key] for mode in event_results])))
|
|
55
|
+
result[i_eval] = event_results[idx]
|
|
56
|
+
result[i_eval]["idx"] = idx
|
|
57
|
+
return result
|
|
58
|
+
|
|
59
|
+
# return {
|
|
60
|
+
# i_eval: event_results[np.argmin(np.abs(mean - np.array([mode[key] for mode in event_results])))]
|
|
61
|
+
# if event_results and len(event_results) > 0 else {}
|
|
62
|
+
# for i_eval, event_results in filtered_modes.items()
|
|
63
|
+
# }
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def ff(asset, pid, key):
|
|
67
|
+
# evaluation_data
|
|
68
|
+
dd = mkdd(asset, pid, key)
|
|
69
|
+
|
|
70
|
+
aa = _ssid_stats(asset, pid, key)
|
|
71
|
+
|
|
72
|
+
for event in aa:
|
|
73
|
+
aa[event]["bb"] = 0.0
|
|
74
|
+
for other_event in aa:
|
|
75
|
+
if other_event != event :
|
|
76
|
+
if assoc(dd[event], dd[other_event])[event] == event:
|
|
77
|
+
aa[event]["bb"] += 1/(len(aa)-1)
|
|
78
|
+
|
|
79
|
+
HELP = """
|
|
80
|
+
modeID [options] <baseline> <unknown>
|
|
81
|
+
|
|
82
|
+
OeventPTIONS:
|
|
83
|
+
-c<compare-mode> compare mode, currently only 'max' supported
|
|
84
|
+
|
|
85
|
+
EXAMPLES:
|
|
86
|
+
|
|
87
|
+
Default compare:
|
|
88
|
+
modeID baseline.yaml unknown.yaml
|
|
89
|
+
|
|
90
|
+
To use `max` compare mode:
|
|
91
|
+
modeID -cmax baseline.yaml unknown.yaml
|
|
92
|
+
or
|
|
93
|
+
modeID -c max baseline.yaml unknown.yaml
|
|
94
|
+
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
import yaml
|
|
98
|
+
import numpy as np
|
|
99
|
+
import sys
|
|
100
|
+
|
|
101
|
+
TOL = 1e-14
|
|
102
|
+
|
|
103
|
+
def _clean_modes(modes, tol=1e-14):
|
|
104
|
+
"Zero-out small values"
|
|
105
|
+
mode_array = np.array([
|
|
106
|
+
[val for node in mode.values() for val in node]
|
|
107
|
+
for mode in modes.values()
|
|
108
|
+
])
|
|
109
|
+
mode_array[abs(mode_array) < tol] = 0.0
|
|
110
|
+
return mode_array
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def associate_modes(baseline, unidentified_dict, compare = None, verbose=True):
|
|
114
|
+
identified_keys = set()
|
|
115
|
+
identified = {}
|
|
116
|
+
_old_labels = list(unidentified_dict.keys())
|
|
117
|
+
|
|
118
|
+
if compare is None:
|
|
119
|
+
_compare = lambda errors, labels: np.argmin(errors)
|
|
120
|
+
|
|
121
|
+
elif compare == "max":
|
|
122
|
+
_compare = lambda errors, labels: np.argmax(errors[~np.isin(np.arange(len(errors)), labels)])
|
|
123
|
+
|
|
124
|
+
unidentified = _clean_modes(unidentified_dict, tol=TOL)
|
|
125
|
+
|
|
126
|
+
for key, mode in baseline.items():
|
|
127
|
+
#
|
|
128
|
+
baseline_data = np.array([*mode.values()]).flatten()
|
|
129
|
+
baseline_data[abs(baseline_data) < TOL] = 0.0
|
|
130
|
+
scale_index = np.argmax(np.absolute(baseline_data))
|
|
131
|
+
baseline_scale = baseline_data[scale_index]
|
|
132
|
+
|
|
133
|
+
errors = np.sum(abs(baseline_data - unidentified*baseline_scale/unidentified[:,scale_index][:,None]), axis=1)
|
|
134
|
+
|
|
135
|
+
# Get index of mode from <unidentified> that is closest to `mode`
|
|
136
|
+
index = _compare(errors, identified_keys)
|
|
137
|
+
old_label = _old_labels[index]
|
|
138
|
+
|
|
139
|
+
if verbose:
|
|
140
|
+
print(f"{old_label} -> {key}", file=sys.stderr)
|
|
141
|
+
|
|
142
|
+
if old_label in identified_keys and verbose:
|
|
143
|
+
print(f"WARNING: duplicate identification of key {old_label}", file=sys.stderr)
|
|
144
|
+
|
|
145
|
+
identified_keys.add(_old_labels[index])
|
|
146
|
+
identified[key] = unidentified[index]
|
|
147
|
+
|
|
148
|
+
return identified
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
if __name__ == "__main__":
|
|
152
|
+
# Parse command line
|
|
153
|
+
index = 1
|
|
154
|
+
compare_mode = None
|
|
155
|
+
if "-c" in sys.argv[1]:
|
|
156
|
+
index += 1
|
|
157
|
+
if len(sys.argv[1]) > 2:
|
|
158
|
+
compare_mode = sys.argv[1][2:]
|
|
159
|
+
else:
|
|
160
|
+
compare_mode = sys.argv[index]
|
|
161
|
+
index += 1
|
|
162
|
+
|
|
163
|
+
baseline_file, unidentified_file = sys.argv[index:]
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# Open Files
|
|
167
|
+
with open(unidentified_file, "r") as f:
|
|
168
|
+
unidentified = yaml.load(f, Loader=yaml.Loader)
|
|
169
|
+
|
|
170
|
+
with open(baseline_file, "r") as f:
|
|
171
|
+
baseline = yaml.load(f, Loader=yaml.Loader)
|
|
172
|
+
|
|
173
|
+
for nodes in unidentified.values():
|
|
174
|
+
node_names = list(nodes.keys())
|
|
175
|
+
break
|
|
176
|
+
|
|
177
|
+
# print(yaml.dump(
|
|
178
|
+
# {
|
|
179
|
+
# key: {
|
|
180
|
+
# node_name: [float(v) for v in node_vals]
|
|
181
|
+
# for node_name, node_vals in
|
|
182
|
+
# zip(node_names, mode.reshape((-1, len(node_names))).T)
|
|
183
|
+
# } for key, mode in
|
|
184
|
+
# associate_modes(baseline, unidentified, compare=compare).items()
|
|
185
|
+
# }
|
|
186
|
+
# ))
|
|
187
|
+
|
|
188
|
+
# for k,mode in associate_modes(baseline, unidentified, compare=compare).items():
|
|
189
|
+
# print(f"{k}:\n\t")
|
|
190
|
+
# print("\n\t".join((f"{node_name}: [{','.join(str(v) for v in node_vals)}]"
|
|
191
|
+
# for node_name, node_vals in
|
|
192
|
+
# zip(node_names, mode.reshape((-1, len(node_names))).T)
|
|
193
|
+
# )))
|
|
194
|
+
|
|
195
|
+
associate_modes(baseline, unidentified, compare=compare_mode)
|
|
196
|
+
|