irie 0.0.49__py3-none-any.whl → 0.0.51__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 (37) hide show
  1. irie/apps/inventory/filters.py +11 -29
  2. irie/apps/inventory/models.py +3 -3
  3. irie/apps/inventory/views.py +9 -2
  4. irie/apps/prediction/admin.py +2 -1
  5. irie/apps/prediction/migrations/0004_sensorassignment.py +31 -0
  6. irie/apps/prediction/migrations/0005_remove_sensorassignment_offset_x_and_more.py +53 -0
  7. irie/apps/prediction/migrations/0006_remove_sensorassignment_show_x_and_more.py +25 -0
  8. irie/apps/prediction/models.py +22 -3
  9. irie/apps/prediction/runners/__init__.py +11 -2
  10. irie/apps/prediction/runners/opensees/__init__.py +114 -62
  11. irie/apps/prediction/runners/ssid.py +9 -10
  12. irie/apps/prediction/urls.py +12 -7
  13. irie/apps/prediction/views.py +81 -24
  14. irie/apps/static/assets/css/brace.css +5 -31
  15. irie/apps/static/assets/css/brace.css.map +1 -1
  16. irie/apps/static/assets/css/brace.min.css +2 -2
  17. irie/apps/templates/components/json-table.html +1 -0
  18. irie/apps/templates/includes/paginate.js +6 -0
  19. irie/apps/templates/includes/scripts.html +7 -20
  20. irie/apps/templates/inventory/asset-on-map.html +5 -5
  21. irie/apps/templates/inventory/sensor-upload.html +97 -262
  22. irie/apps/templates/networks/{networks.html → _networks.html} +0 -1
  23. irie/apps/templates/networks/networks.js +6 -4
  24. irie/apps/templates/prediction/asset-predictors.html +41 -47
  25. irie/apps/templates/prediction/{form-submission.html → create-mdof.html} +0 -21
  26. irie/apps/templates/prediction/new-runner.html +0 -20
  27. irie/apps/templates/prediction/predictor-profile.html +8 -134
  28. irie/apps/templates/prediction/viewer/veux-viewer.js +186 -0
  29. irie/apps/templates/prediction/xara-profile.html +221 -0
  30. irie/apps/templates/sensors/render-sensors.js +152 -0
  31. irie/init/management/commands/init_cesmd.py +2 -2
  32. {irie-0.0.49.dist-info → irie-0.0.51.dist-info}/METADATA +2 -3
  33. {irie-0.0.49.dist-info → irie-0.0.51.dist-info}/RECORD +37 -30
  34. {irie-0.0.49.dist-info → irie-0.0.51.dist-info}/WHEEL +1 -1
  35. /irie/apps/templates/prediction/{predictor-upload.html → create-model.html} +0 -0
  36. {irie-0.0.49.dist-info → irie-0.0.51.dist-info}/entry_points.txt +0 -0
  37. {irie-0.0.49.dist-info → irie-0.0.51.dist-info}/top_level.txt +0 -0
@@ -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='Search'
8
+ label="Search"
9
9
  )
10
10
 
11
11
  cesmd_not_null = django_filters.BooleanFilter(
12
- label='Instrumented',
12
+ label="Instrumented",
13
13
  widget=CheckboxInput(),
14
- method='filter_cesmd_exists'
14
+ method="filter_cesmd_exists"
15
15
  )
16
16
 
17
17
  is_streaming = django_filters.BooleanFilter(
18
- # field_name='is_complete',
19
- label='Streaming',
18
+ # field_name="is_complete",
19
+ label="Streaming",
20
20
  widget=CheckboxInput(),
21
- method='filter_is_streaming'
21
+ method="filter_is_streaming"
22
22
  )
23
23
 
24
24
  district = django_filters.CharFilter(
25
- label='District',
26
- method='filter_district'
25
+ label="District",
26
+ method="filter_district"
27
27
  )
28
28
 
29
29
  max_year = django_filters.NumberFilter(
30
- label='Max Year',
31
- method='filter_year',
32
- # widget=django_filters.widgets.DateInput(attrs={'type': 'date'})
30
+ label="Max Year",
31
+ method="filter_year"
33
32
  )
34
- # max_year = django_filters.DateFilter(
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):
@@ -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.name} - {self.datum}"
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
 
@@ -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
@@ -439,12 +440,18 @@ def sensor_upload(request, calid):
439
440
  group_form = SensorGroupForm(asset=asset)
440
441
  formset = SensorFormSet()
441
442
 
442
- return render(request, "inventory/sensor-upload.html", {
443
+ context = {
443
444
  "group_form": group_form,
444
445
  "formset": formset,
446
+ "renderings": [
447
+ {"name": predictor.name, "glb": predictor.render_file.url}
448
+ for predictor in PredictorModel.objects.filter(asset=asset, protocol="IRIE_PREDICTOR_V1")
449
+ if predictor.render_file and predictor.render_file.url
450
+ ],
445
451
  "asset": asset,
446
452
  "datums": list(datums)
447
- })
453
+ }
454
+ return render(request, "inventory/sensor-upload.html", context)
448
455
 
449
456
 
450
457
  def _filter_asset_table(request):
@@ -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
+ ]
@@ -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,17 @@ 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
  self.model_file = Path(pred.config_file.path).resolve()
43
49
  self.out_dir = Path(__file__).parents[0]/"Predictions"
50
+ else:
51
+ self.model_file = None
52
+ self.out_dir = None
44
53
  self.runs = {}
45
54
 
46
55
  @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 subprocess
504
- class Event: pass
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
- @classproperty
530
- def schema(cls):
531
- from irie.apps.prediction.runners.opensees import schemas
532
- return {
533
- "title": "Structural Model",
534
- "options": {"disable_collaps": True},
535
- "schema": "http://json-schema.org/draft-04/schema#",
536
- "type": "object",
537
- "properties": {
538
- "platform": {
539
- "type": "string",
540
- "title": "Platform",
541
- "enum": ["OpenSees","CSiBridge"]
542
- },
543
- "model": schemas.load("hwd_conf.schema.json"),
544
- "analysis": schemas.load("hwd_analysis.schema.json"),
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
- def newPrediction(self, event: Event) -> RunID:
549
- self.event = event
550
- event_file = Path(event.event_file.path).resolve()
551
- command = [*self.entry_point, "new", event_file]
552
- run_id = subprocess.check_output(command).decode().strip()
553
- return RunID(int(run_id))
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
- def getMetricData(self, run, metric):
567
- try:
568
- return json.loads(subprocess.check_output([*self.entry_point, "get", str(run), metric]).decode())
569
- except json.decoder.JSONDecodeError:
570
- return {}
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,13 @@ import io
13
13
  import base64
14
14
  import numpy as np
15
15
  # Ensure Agg backend is set for non-interactive plotting
16
- import matplotlib
17
- matplotlib.use('Agg')
18
- from matplotlib import pyplot as plt, ticker, cm
16
+
19
17
  import quakeio
20
18
  from mdof import transform
21
19
  from scipy.signal import find_peaks
22
20
  from mdof.utilities import Config, extract_channels
23
- from matplotlib import colormaps
24
21
  import subprocess
25
- # try:
26
- # import scienceplots
27
- # plt.style.use(["science"])
28
- # except ImportError:
29
- # pass
22
+
30
23
 
31
24
  N_PEAKS = 5 # number of "significant" peaks per record
32
25
  MISSING_CHANNEL_LIMIT = 3 # number of missing output channels allowed before skipping event
@@ -439,6 +432,10 @@ def plot_spectral_surface(ax, traces, **options):
439
432
 
440
433
 
441
434
  def _plot_mountains(spectra, accellim=None):
435
+ import matplotlib
436
+ matplotlib.use('Agg')
437
+ from matplotlib import pyplot as plt, ticker, cm
438
+ from matplotlib import colormaps
442
439
  fig = plt.figure(figsize=(13,13))
443
440
  ax = fig.add_subplot(projection='3d')
444
441
 
@@ -512,7 +509,6 @@ def make_mountains(asset, conf=None, output_channels=None):
512
509
  buffer = io.BytesIO()
513
510
  fig.savefig(buffer, format="png")
514
511
  buffer.seek(0)
515
- # plt.show()
516
512
 
517
513
  # Encode the image as Base64
518
514
  return base64.b64encode(buffer.read()).decode("utf-8")
@@ -549,6 +545,9 @@ def parse_args(args):
549
545
  if __name__ == '__main__':
550
546
 
551
547
  import sys
548
+ from matplotlib import pyplot as plt, ticker, cm
549
+ from matplotlib import colormaps
550
+
552
551
  procedure = parse_args(sys.argv)
553
552
  STATION_TYPE = procedure['STATION_TYPE']
554
553
  outdir = Path(procedure['outdir'])
@@ -8,13 +8,18 @@
8
8
  #
9
9
  #----------------------------------------------------------------------------#
10
10
  from django.urls import re_path
11
- from .views import new_prediction, asset_predictors, predictor_profile, predictor_upload, asset_map
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("^inventory/[0-9 A-Z-]*/predictors/new", new_prediction),
15
- re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/(?P<preid>[0-9 A-Z-]{1,})", predictor_profile),
16
- re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/create/map/$", asset_map),
17
- re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/map/$", asset_map),
18
- re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/create/$", predictor_upload),
19
- re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/", asset_predictors, name="asset_predictors")
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
  ]