Skip to content

Model

Model Documentation sub-package for MaRDMO.

Provides everything needed to document mathematical models within RDMO:

  • :mod:~MaRDMO.model.models — Dataclasses for MathematicalModel, Task, MathematicalFormulation, QuantityOrQuantityKind, ResearchField, and ResearchProblem entities from MaRDI Portal or Wikidata.
  • :mod:~MaRDMO.model.handlers — Signal handlers that populate the questionnaire when an external ID is saved.
  • :mod:~MaRDMO.model.providers — RDMO optionset providers for searching models, formulations, tasks, quantities, and related entities in external knowledge graphs.
  • :mod:~MaRDMO.model.worker — Background worker for generating model previews and exporting model entries to the MaRDI Portal.
  • :mod:~MaRDMO.model.utils — Utility functions for building quantity info and mapping entity-quantity relationships.
  • :mod:~MaRDMO.model.constants — Relation mappings, data-property definitions, and URI-prefix configurations specific to the model catalogs.

Handlers

Module containing Handlers for the Model Documentation.

Information inherits _entry, _collect_existing_ids, _hydrate_relatants, and _fill from BaseInformation (MaRDMO/handler_base.py).

All SPARQL and write logic lives in the fill*_batch methods.

Information

Bases: BaseInformation

Handlers for the Model Documentation questionnaire.

Source code in MaRDMO/model/handlers.py
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
class Information(BaseInformation):
    '''Handlers for the Model Documentation questionnaire.'''

    _ENTITY_KEYS = (
        'Research Field', 'Research Problem', 'Quantity',
        'Mathematical Formulation', 'Task', 'Mathematical Model',
        'Publication',
    )

    def __init__(self):
        '''Load model and publication questions, MathModDB registry, and base URI.'''
        self.questions = get_questions('model') | get_questions('publication')
        self.mathmoddb = get_mathmoddb()
        self.base      = BASE_URI

    # ------------------------------------------------------------------ #
    #  Public signal-handler entry points                                  #
    # ------------------------------------------------------------------ #

    def field(self, instance):
        '''Handle Research Field ID save: hydrate basics and SPARQL data.

        Args:
            instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
        '''
        self._entry(instance, 'Research Field', self._fill_field_batch)

    def problem(self, instance):
        '''Handle Research Problem ID save: hydrate basics and SPARQL data.

        Args:
            instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
        '''
        self._entry(instance, 'Research Problem', self._fill_problem_batch)

    def quantity(self, instance):
        '''Handle Quantity ID save: hydrate basics and SPARQL data.

        Args:
            instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
        '''
        self._entry(instance, 'Quantity', self._fill_quantity_batch)

    def formulation(self, instance):
        '''Handle Mathematical Formulation ID save: hydrate basics and SPARQL data.

        Args:
            instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
        '''
        self._entry(instance, 'Mathematical Formulation', self._fill_formulation_batch)

    def task(self, instance):
        '''Handle Computational Task ID save: hydrate basics and SPARQL data.

        Args:
            instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
        '''
        self._entry(instance, 'Task', self._fill_task_batch)

    def model(self, instance):
        '''Handle Mathematical Model ID save: hydrate basics and SPARQL data.

        Args:
            instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
        '''
        self._entry(instance, 'Mathematical Model', self._fill_model_batch)

    # ------------------------------------------------------------------ #
    #  Model-specific cascade helpers                                      #
    # ------------------------------------------------------------------ #

    def _hydrate_assumptions(self, project, data, prop_keys, catalog, visited):
        '''Hydrate Mathematical Formulation pages referenced as assumption qualifiers.

        Parses assumption qualifier strings from relation relatants, resolves
        the embedded formulation external IDs, and calls :meth:`_fill_formulation_batch`
        for any IDs not yet in the questionnaire.

        Args:
            project:   RDMO project instance.
            data:      Dataclass instance whose relation attributes may carry
                       qualifier strings.
            prop_keys: Iterable of attribute names on *data* to inspect for
                       assumption qualifiers.
            catalog:   Active catalog URI suffix.
            visited:   Set of external IDs already processed (mutated in place).
        '''
        from ..helpers import process_qualifier  # noqa: PLC0415

        mf_id_uri  = f'{self.base}{self.questions["Mathematical Formulation"]["ID"]["uri"]}'
        mf_set_uri = f'{self.base}{self.questions["Mathematical Formulation"]["uri"]}'

        existing = get_id(project, mf_set_uri, ['set_index'])
        next_idx = max((e for e in existing if e is not None), default=-1) + 1

        for prop in prop_keys:
            for relatant in getattr(data, prop, []):
                qualifier = getattr(relatant, 'qualifier', None)
                if not qualifier:
                    continue
                for assumption in process_qualifier(qualifier).values():
                    ext_id = assumption['id']
                    if ext_id in visited:
                        continue
                    visited.add(ext_id)
                    source = ext_id.split(':')[0]
                    text   = (f'{assumption["label"]} '
                              f'({assumption["description"]}) [{source}]')

                    value_editor(project=project, uri=mf_set_uri,
                                 info={'text': f'ME{next_idx + 1}',
                                       'set_index': next_idx})
                    value_editor(project=project, uri=mf_id_uri,
                                 info={'text': text, 'external_id': ext_id,
                                       'set_index': next_idx})

                    self._fill(project=project, text=text, external_id=ext_id,
                               set_index=next_idx,
                               item_type='Mathematical Formulation',
                               batch_fill_method=self._fill_formulation_batch,
                               catalog=catalog, visited=visited)
                    next_idx += 1

    # ------------------------------------------------------------------ #
    #  Batch _fill_* methods (one SPARQL query for N entities)            #
    # ------------------------------------------------------------------ #

    def _fill_field_batch(self, project, items, catalog, visited):
        '''Hydrate multiple Research Field pages with a single SPARQL query per source.

        Args:
            project:  RDMO project instance.
            items:    List of ``(text, external_id, set_index)`` tuples to process.
            catalog:  Active catalog URI suffix.
            visited:  Set of external IDs already processed (mutated to avoid cycles).
        '''
        if not items:
            return

        field      = self.questions['Research Field']
        data_by_id = _fetch_by_source(
            items,
            'model/queries/field_mardi.sparql',
            'model/queries/field_wikidata.sparql',
            models.ResearchField,
        )
        if not data_by_id:
            return

        for text, external_id, set_index in items:
            data = data_by_id.get(external_id)
            if not data:
                continue

            add_basics(project=project, text=text, questions=self.questions,
                       item_type='Research Field', index=(0, set_index))

            for idx, alias in enumerate(data.aliases):
                value_editor(project=project, uri=f'{self.base}{field["Alias"]["uri"]}',
                             info={'text': alias, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            for idx, desc in enumerate(data.description_long):
                value_editor(project=project,
                             uri=f'{self.base}{field["Long Description"]["uri"]}',
                             info={'text': desc, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['Field'], 'mapping': self.mathmoddb},
                index={'set_prefix': set_index},
                statement={
                    'relation': f'{self.base}{field["IntraClassRelation"]["uri"]}',
                    'relatant': f'{self.base}{field["IntraClassElement"]["uri"]}',
                })

            self._hydrate_publications(project, data.publications,
                                       catalog, visited)

    def _fill_problem_batch(self, project, items, catalog, visited):
        '''Hydrate multiple Research Problem pages with a single SPARQL query per source.

        Args:
            project:  RDMO project instance.
            items:    List of ``(text, external_id, set_index)`` tuples to process.
            catalog:  Active catalog URI suffix.
            visited:  Set of external IDs already processed (mutated to avoid cycles).
        '''
        if not items:
            return

        problem    = self.questions['Research Problem']
        data_by_id = _fetch_by_source(
            items,
            _sparql_file('model/queries/problem_mardi.sparql', catalog),
            _sparql_file('model/queries/problem_wikidata.sparql', catalog),
            models.ResearchProblem,
        )
        if not data_by_id:
            return

        section_indices = {}
        for text, external_id, set_index in items:
            data = data_by_id.get(external_id)
            if not data:
                continue

            add_basics(project=project, text=text, questions=self.questions,
                       item_type='Research Problem', index=(0, set_index))

            for idx, alias in enumerate(data.aliases):
                value_editor(project=project, uri=f'{self.base}{problem["Alias"]["uri"]}',
                             info={'text': alias, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            for idx, desc in enumerate(data.description_long):
                value_editor(project=project,
                             uri=f'{self.base}{problem["Long Description"]["uri"]}',
                             info={'text': desc, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            add_relations_static(
                project=project, data=data,
                props={'keys': props['RP2RF']},
                index={'set_prefix': set_index},
                statement={'relatant': f'{self.base}{problem["RFRelatant"]["uri"]}'})

            self._hydrate_relatants(
                project=project, data=data, prop_keys=props['RP2RF'],
                spec=_RelatantSpec(
                    question_id_uri=f'{self.base}{self.questions["Research Field"]["ID"]["uri"]}',
                    question_set_uri=f'{self.base}{self.questions["Research Field"]["uri"]}',
                    prefix='AD',
                    fill_method=partial(self._fill, item_type='Research Field',
                                        batch_fill_method=self._fill_field_batch),
                    catalog=catalog, visited=visited,
                    batch_fill_method=self._fill_field_batch,
                    section_indices=section_indices,
                ))

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['Problem'], 'mapping': self.mathmoddb},
                index={'set_prefix': set_index},
                statement={
                    'relation': f'{self.base}{problem["IntraClassRelation"]["uri"]}',
                    'relatant': f'{self.base}{problem["IntraClassElement"]["uri"]}',
                })

            self._hydrate_publications(project, data.publications,
                                       catalog, visited)

    def _fill_quantity_batch(self, project, items, catalog, visited):
        '''Hydrate multiple Quantity [Kind] pages with a single SPARQL query per source.

        Args:
            project:  RDMO project instance.
            items:    List of ``(text, external_id, set_index)`` tuples to process.
            catalog:  Active catalog URI suffix.
            visited:  Set of external IDs already processed (mutated to avoid cycles).
        '''
        if not items:
            return

        quantity   = self.questions['Quantity']
        data_by_id = _fetch_by_source(
            items,
            'model/queries/quantity_mardi.sparql',
            'model/queries/quantity_wikidata.sparql',
            models.QuantityOrQuantityKind,
        )
        if not data_by_id:
            return

        # Fetch formula data via API for mardi items
        mardi_qids = [eid.split(':')[-1] for _, eid, _ in items if eid.startswith('mardi:')]
        formula_data = models.fetch_formula_data(mardi_qids)
        for _, external_id, _ in items:
            if external_id.startswith('mardi:') and external_id in data_by_id:
                qid = external_id.split(':')[-1]
                if qid in formula_data:
                    fd = formula_data[qid]
                    data_by_id[external_id].formulas          = fd['formulas']
                    data_by_id[external_id].symbols           = fd['symbols']
                    data_by_id[external_id].contains_quantity = fd['contains_quantity']

        for text, external_id, set_index in items:
            data = data_by_id.get(external_id)
            if not data:
                continue

            add_basics(project=project, text=text, questions=self.questions,
                       item_type='Quantity', index=(0, set_index))

            for idx, alias in enumerate(data.aliases):
                value_editor(project=project, uri=f'{self.base}{quantity["Alias"]["uri"]}',
                             info={'text': alias, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            for idx, desc in enumerate(data.description_long):
                value_editor(project=project,
                             uri=f'{self.base}{quantity["Long Description"]["uri"]}',
                             info={'text': desc, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            if data.qclass:
                value_editor(project=project, uri=f'{self.base}{quantity["QorQK"]["uri"]}',
                             info={'option': Option.objects.get(
                                       uri=self.mathmoddb.get(key=data.qclass)['url']),
                                   'set_index': set_index})

            add_properties(project=project, data=data,
                           uri=f'{self.base}{quantity["Properties"]["uri"]}',
                           set_prefix=set_index)
            add_references(project=project, data=data,
                           uri=f'{self.base}{quantity["Reference"]["uri"]}',
                           set_prefix=set_index)

            for idx, formula in enumerate(data.formulas):
                value_editor(project=project, uri=f'{self.base}{quantity["Formula"]["uri"]}',
                             info={'text': formula, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': f'{set_index}|0'})

            for idx, symbol in enumerate(data.symbols):
                value_editor(project=project,
                             uri=f'{self.base}{quantity["Element Symbol"]["uri"]}',
                             info={'text': symbol, 'set_index': idx,
                                   'set_prefix': f'{set_index}|0|0'})

            for idx, qty in enumerate(data.contains_quantity):
                src_q = qty.id.split(':')[0]
                value_editor(project=project,
                             uri=f'{self.base}{quantity["Element Quantity"]["uri"]}',
                             info={'text': f'{qty.label} ({qty.description}) [{src_q}]',
                                   'external_id': qty.id, 'set_index': idx,
                                   'set_prefix': f'{set_index}|0|0'})

            for prop in props['Quantity']:
                for val in getattr(data, prop):
                    pair = (data.qclass, val.item_class)
                    value_editor(
                        project=project,
                        uri=f'{self.base}{quantity[relation_uris[pair]]["uri"]}',
                        info={'option': Option.objects.get(
                                  uri=self.mathmoddb.get(key=prop)['url']),
                              'set_index': index_counters[pair],
                              'set_prefix': str(set_index)})
                    value_editor(
                        project=project,
                        uri=f'{self.base}{quantity[relatant_uris[pair]]["uri"]}',
                        info={'text': f'{val.label} ({val.description}) [mardi]',
                              'external_id': val.id,
                              'set_index': index_counters[pair],
                              'set_prefix': str(set_index)})
                    index_counters[pair] += 1

            self._hydrate_publications(project, data.publications,
                                       catalog, visited)

    def _fill_formulation_batch(self, project, items, catalog, visited):
        '''Hydrate multiple Mathematical Formulation pages with a single SPARQL query per source.

        Args:
            project:  RDMO project instance.
            items:    List of ``(text, external_id, set_index)`` tuples to process.
            catalog:  Active catalog URI suffix.
            visited:  Set of external IDs already processed (mutated to avoid cycles).
        '''
        if not items:
            return

        formulation = self.questions['Mathematical Formulation']
        data_by_id  = _fetch_by_source(
            items,
            _sparql_file('model/queries/formulation_mardi.sparql', catalog),
            _sparql_file('model/queries/formulation_wikidata.sparql', catalog),
            models.MathematicalFormulation,
        )
        if not data_by_id:
            return

        # Fetch formula data via API for mardi items
        mardi_qids = [eid.split(':')[-1] for _, eid, _ in items if eid.startswith('mardi:')]
        formula_data = models.fetch_formula_data(mardi_qids)
        for _, external_id, _ in items:
            if external_id.startswith('mardi:') and external_id in data_by_id:
                qid = external_id.split(':')[-1]
                if qid in formula_data:
                    fd = formula_data[qid]
                    data_by_id[external_id].formulas          = fd['formulas']
                    data_by_id[external_id].symbols           = fd['symbols']
                    data_by_id[external_id].contains_quantity = fd['contains_quantity']

        section_indices = {}
        for text, external_id, set_index in items:
            data = data_by_id.get(external_id)
            if not data:
                continue

            add_basics(project=project, text=text, questions=self.questions,
                       item_type='Mathematical Formulation', index=(0, set_index))

            for idx, alias in enumerate(data.aliases):
                value_editor(project=project,
                             uri=f'{self.base}{formulation["Alias"]["uri"]}',
                             info={'text': alias, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            for idx, desc in enumerate(data.description_long):
                value_editor(project=project,
                             uri=f'{self.base}{formulation["Long Description"]["uri"]}',
                             info={'text': desc, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            add_properties(project=project, data=data,
                           uri=f'{self.base}{formulation["Properties"]["uri"]}',
                           set_prefix=set_index)

            for idx, formula in enumerate(data.formulas):
                value_editor(project=project,
                             uri=f'{self.base}{formulation["Formula"]["uri"]}',
                             info={'text': formula, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': f'{set_index}|0'})

            for idx, symbol in enumerate(data.symbols):
                value_editor(project=project,
                             uri=f'{self.base}{formulation["Element Symbol"]["uri"]}',
                             info={'text': symbol, 'set_index': idx,
                                   'set_prefix': f'{set_index}|0|0'})

            for idx, qty in enumerate(data.contains_quantity):
                src_q = qty.id.split(':')[0]
                value_editor(project=project,
                             uri=f'{self.base}{formulation["Element Quantity"]["uri"]}',
                             info={'text': f'{qty.label} ({qty.description}) [{src_q}]',
                                   'external_id': qty.id, 'set_index': idx,
                                   'set_prefix': f'{set_index}|0|0'})

            self._hydrate_relatants(
                project=project, data=data, prop_keys=['contains_quantity'],
                spec=_RelatantSpec(
                    question_id_uri=f'{self.base}{self.questions["Quantity"]["ID"]["uri"]}',
                    question_set_uri=f'{self.base}{self.questions["Quantity"]["uri"]}',
                    prefix='QQK',
                    fill_method=partial(self._fill, item_type='Quantity',
                                        batch_fill_method=self._fill_quantity_batch),
                    catalog=catalog, visited=visited,
                    batch_fill_method=self._fill_quantity_batch,
                    section_indices=section_indices,
                ))

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['MF2MF'], 'mapping': self.mathmoddb},
                index={'set_prefix': f'{set_index}|0'},
                statement={
                    'relation': f'{self.base}{formulation["MF2MF"]["uri"]}',
                    'relatant': f'{self.base}{formulation["MFRelatant"]["uri"]}',
                })

            self._hydrate_relatants(
                project=project, data=data, prop_keys=props['MF2MF'],
                spec=_RelatantSpec(
                    question_id_uri=(
                        f'{self.base}{self.questions["Mathematical Formulation"]["ID"]["uri"]}'),
                    question_set_uri=(
                        f'{self.base}{self.questions["Mathematical Formulation"]["uri"]}'),
                    prefix='ME',
                    fill_method=partial(self._fill, item_type='Mathematical Formulation',
                                        batch_fill_method=self._fill_formulation_batch),
                    catalog=catalog, visited=visited,
                    batch_fill_method=self._fill_formulation_batch,
                    section_indices=section_indices,
                ))

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['Formulation'], 'mapping': self.mathmoddb},
                index={'set_prefix': set_index},
                statement={
                    'relation':   f'{self.base}{formulation["IntraClassRelation"]["uri"]}',
                    'relatant':   f'{self.base}{formulation["IntraClassElement"]["uri"]}',
                    'assumption': f'{self.base}{formulation["Assumption"]["uri"]}',
                })

            self._hydrate_assumptions(project, data, props['Formulation'],
                                      catalog, visited)
            self._hydrate_publications(project, data.publications,
                                       catalog, visited)

    def _fill_task_batch(self, project, items, catalog, visited):
        '''Hydrate multiple Computational Task pages with a single SPARQL query per source.

        Args:
            project:  RDMO project instance.
            items:    List of ``(text, external_id, set_index)`` tuples to process.
            catalog:  Active catalog URI suffix.
            visited:  Set of external IDs already processed (mutated to avoid cycles).
        '''
        if not items:
            return

        task       = self.questions['Task']
        data_by_id = _fetch_by_source(
            items,
            _sparql_file('model/queries/task_mardi.sparql', catalog),
            _sparql_file('model/queries/task_wikidata.sparql', catalog),
            models.Task,
        )
        if not data_by_id:
            return

        section_indices = {}
        for text, external_id, set_index in items:
            data = data_by_id.get(external_id)
            if not data:
                continue

            add_basics(project=project, text=text, questions=self.questions,
                       item_type='Task', index=(0, set_index))

            for idx, alias in enumerate(data.aliases):
                value_editor(project=project, uri=f'{self.base}{task["Alias"]["uri"]}',
                             info={'text': alias, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            for idx, desc in enumerate(data.description_long):
                value_editor(project=project,
                             uri=f'{self.base}{task["Long Description"]["uri"]}',
                             info={'text': desc, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            add_properties(project=project, data=data,
                           uri=f'{self.base}{task["Properties"]["uri"]}',
                           set_prefix=set_index)

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['T2MF'], 'mapping': self.mathmoddb},
                index={'set_prefix': f'{set_index}|0'},
                statement={
                    'relation': f'{self.base}{task["T2MF"]["uri"]}',
                    'relatant': f'{self.base}{task["MFRelatant"]["uri"]}',
                })

            self._hydrate_relatants(
                project=project, data=data, prop_keys=props['T2MF'],
                spec=_RelatantSpec(
                    question_id_uri=(
                        f'{self.base}{self.questions["Mathematical Formulation"]["ID"]["uri"]}'),
                    question_set_uri=(
                        f'{self.base}{self.questions["Mathematical Formulation"]["uri"]}'),
                    prefix='ME',
                    fill_method=partial(self._fill, item_type='Mathematical Formulation',
                                        batch_fill_method=self._fill_formulation_batch),
                    catalog=catalog, visited=visited,
                    batch_fill_method=self._fill_formulation_batch,
                    section_indices=section_indices,
                ))

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['T2Q'], 'mapping': self.mathmoddb},
                index={'set_prefix': f'{set_index}|0'},
                statement={
                    'relation': f'{self.base}{task["T2Q"]["uri"]}',
                    'relatant': f'{self.base}{task["QRelatant"]["uri"]}',
                })

            self._hydrate_relatants(
                project=project, data=data, prop_keys=props['T2Q'],
                spec=_RelatantSpec(
                    question_id_uri=f'{self.base}{self.questions["Quantity"]["ID"]["uri"]}',
                    question_set_uri=f'{self.base}{self.questions["Quantity"]["uri"]}',
                    prefix='QQK',
                    fill_method=partial(self._fill, item_type='Quantity',
                                        batch_fill_method=self._fill_quantity_batch),
                    catalog=catalog, visited=visited,
                    batch_fill_method=self._fill_quantity_batch,
                    section_indices=section_indices,
                ))

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['Task'], 'mapping': self.mathmoddb},
                index={'set_prefix': set_index},
                statement={
                    'relation':   f'{self.base}{task["IntraClassRelation"]["uri"]}',
                    'relatant':   f'{self.base}{task["IntraClassElement"]["uri"]}',
                    'assumption': f'{self.base}{task["Assumption"]["uri"]}',
                    'order':      f'{self.base}{task["Order Number"]["uri"]}',
                })

            self._hydrate_assumptions(project, data, props['Task'], catalog, visited)
            self._hydrate_publications(project, data.publications,
                                       catalog, visited)

    def _fill_model_batch(self, project, items, catalog, visited):
        '''Hydrate multiple Mathematical Model pages with a single SPARQL query per source.

        Args:
            project:  RDMO project instance.
            items:    List of ``(text, external_id, set_index)`` tuples to process.
            catalog:  Active catalog URI suffix.
            visited:  Set of external IDs already processed (mutated to avoid cycles).
        '''
        if not items:
            return

        model_q    = self.questions['Mathematical Model']
        data_by_id = _fetch_by_source(
            items,
            _sparql_file('model/queries/model_mardi.sparql', catalog),
            _sparql_file('model/queries/model_wikidata.sparql', catalog),
            models.MathematicalModel,
        )
        if not data_by_id:
            return

        section_indices = {}
        for text, external_id, set_index in items:
            data = data_by_id.get(external_id)
            if not data:
                continue

            add_basics(project=project, text=text, questions=self.questions,
                       item_type='Mathematical Model', index=(0, set_index))

            for idx, alias in enumerate(data.aliases):
                value_editor(project=project, uri=f'{self.base}{model_q["Alias"]["uri"]}',
                             info={'text': alias, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            for idx, desc in enumerate(data.description_long):
                value_editor(project=project,
                             uri=f'{self.base}{model_q["Long Description"]["uri"]}',
                             info={'text': desc, 'collection_index': idx,
                                   'set_index': 0, 'set_prefix': set_index})

            add_properties(project=project, data=data,
                           uri=f'{self.base}{model_q["Properties"]["uri"]}',
                           set_prefix=set_index)

            add_relations_static(
                project=project, data=data,
                props={'keys': props['MM2RP']},
                index={'set_prefix': set_index},
                statement={'relatant': f'{self.base}{model_q["RPRelatant"]["uri"]}'})

            self._hydrate_relatants(
                project=project, data=data, prop_keys=props['MM2RP'],
                spec=_RelatantSpec(
                    question_id_uri=f'{self.base}{self.questions["Research Problem"]["ID"]["uri"]}',
                    question_set_uri=f'{self.base}{self.questions["Research Problem"]["uri"]}',
                    prefix='RP',
                    fill_method=partial(self._fill, item_type='Research Problem',
                                        batch_fill_method=self._fill_problem_batch),
                    catalog=catalog, visited=visited,
                    batch_fill_method=self._fill_problem_batch,
                    section_indices=section_indices,
                ))

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['MM2MF'], 'mapping': self.mathmoddb},
                index={'set_prefix': f'{set_index}|0'},
                statement={
                    'relation': f'{self.base}{model_q["MM2MF"]["uri"]}',
                    'relatant': f'{self.base}{model_q["MFRelatant"]["uri"]}',
                    'order':    f'{self.base}{model_q["Order Number"]["uri"]}',
                })

            self._hydrate_relatants(
                project=project, data=data, prop_keys=props['MM2MF'],
                spec=_RelatantSpec(
                    question_id_uri=(
                        f'{self.base}{self.questions["Mathematical Formulation"]["ID"]["uri"]}'),
                    question_set_uri=(
                        f'{self.base}{self.questions["Mathematical Formulation"]["uri"]}'),
                    prefix='ME',
                    fill_method=partial(self._fill, item_type='Mathematical Formulation',
                                        batch_fill_method=self._fill_formulation_batch),
                    catalog=catalog, visited=visited,
                    batch_fill_method=self._fill_formulation_batch,
                    section_indices=section_indices,
                ))

            add_relations_static(
                project=project, data=data,
                props={'keys': props['MM2T']},
                index={'set_prefix': set_index},
                statement={'relatant': f'{self.base}{model_q["TRelatant"]["uri"]}'})

            self._hydrate_relatants(
                project=project, data=data, prop_keys=props['MM2T'],
                spec=_RelatantSpec(
                    question_id_uri=f'{self.base}{self.questions["Task"]["ID"]["uri"]}',
                    question_set_uri=f'{self.base}{self.questions["Task"]["uri"]}',
                    prefix='CT',
                    fill_method=partial(self._fill, item_type='Task',
                                        batch_fill_method=self._fill_task_batch),
                    catalog=catalog, visited=visited,
                    batch_fill_method=self._fill_task_batch,
                    section_indices=section_indices,
                ))

            add_relations_flexible(
                project=project, data=data,
                props={'keys': props['Model'], 'mapping': self.mathmoddb},
                index={'set_prefix': set_index},
                statement={
                    'relation':   f'{self.base}{model_q["IntraClassRelation"]["uri"]}',
                    'relatant':   f'{self.base}{model_q["IntraClassElement"]["uri"]}',
                    'assumption': f'{self.base}{model_q["Assumption"]["uri"]}',
                })

            self._hydrate_assumptions(project, data, props['Model'], catalog, visited)
            self._hydrate_publications(project, data.publications,
                                       catalog, visited)

__init__()

Load model and publication questions, MathModDB registry, and base URI.

Source code in MaRDMO/model/handlers.py
57
58
59
60
61
def __init__(self):
    '''Load model and publication questions, MathModDB registry, and base URI.'''
    self.questions = get_questions('model') | get_questions('publication')
    self.mathmoddb = get_mathmoddb()
    self.base      = BASE_URI

field(instance)

Handle Research Field ID save: hydrate basics and SPARQL data.

Parameters:

Name Type Description Default
instance

RDMO :class:~rdmo.projects.models.Value that was just saved.

required
Source code in MaRDMO/model/handlers.py
67
68
69
70
71
72
73
def field(self, instance):
    '''Handle Research Field ID save: hydrate basics and SPARQL data.

    Args:
        instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
    '''
    self._entry(instance, 'Research Field', self._fill_field_batch)

formulation(instance)

Handle Mathematical Formulation ID save: hydrate basics and SPARQL data.

Parameters:

Name Type Description Default
instance

RDMO :class:~rdmo.projects.models.Value that was just saved.

required
Source code in MaRDMO/model/handlers.py
91
92
93
94
95
96
97
def formulation(self, instance):
    '''Handle Mathematical Formulation ID save: hydrate basics and SPARQL data.

    Args:
        instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
    '''
    self._entry(instance, 'Mathematical Formulation', self._fill_formulation_batch)

model(instance)

Handle Mathematical Model ID save: hydrate basics and SPARQL data.

Parameters:

Name Type Description Default
instance

RDMO :class:~rdmo.projects.models.Value that was just saved.

required
Source code in MaRDMO/model/handlers.py
107
108
109
110
111
112
113
def model(self, instance):
    '''Handle Mathematical Model ID save: hydrate basics and SPARQL data.

    Args:
        instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
    '''
    self._entry(instance, 'Mathematical Model', self._fill_model_batch)

problem(instance)

Handle Research Problem ID save: hydrate basics and SPARQL data.

Parameters:

Name Type Description Default
instance

RDMO :class:~rdmo.projects.models.Value that was just saved.

required
Source code in MaRDMO/model/handlers.py
75
76
77
78
79
80
81
def problem(self, instance):
    '''Handle Research Problem ID save: hydrate basics and SPARQL data.

    Args:
        instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
    '''
    self._entry(instance, 'Research Problem', self._fill_problem_batch)

quantity(instance)

Handle Quantity ID save: hydrate basics and SPARQL data.

Parameters:

Name Type Description Default
instance

RDMO :class:~rdmo.projects.models.Value that was just saved.

required
Source code in MaRDMO/model/handlers.py
83
84
85
86
87
88
89
def quantity(self, instance):
    '''Handle Quantity ID save: hydrate basics and SPARQL data.

    Args:
        instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
    '''
    self._entry(instance, 'Quantity', self._fill_quantity_batch)

task(instance)

Handle Computational Task ID save: hydrate basics and SPARQL data.

Parameters:

Name Type Description Default
instance

RDMO :class:~rdmo.projects.models.Value that was just saved.

required
Source code in MaRDMO/model/handlers.py
 99
100
101
102
103
104
105
def task(self, instance):
    '''Handle Computational Task ID save: hydrate basics and SPARQL data.

    Args:
        instance: RDMO :class:`~rdmo.projects.models.Value` that was just saved.
    '''
    self._entry(instance, 'Task', self._fill_task_batch)

Models

Dataclasses and fetch helpers that represent entities in the Model catalog.

Each class maps to one entity type collected from MaRDI Portal and Wikidata during model documentation. Instances are populated from SPARQL query results and carry the fields needed to render questionnaire answers and export entries.

Provides:

  • :class:RelatantWithQualifier — entity triple extended with a qualifier value
  • :class:ResearchField — mathematical research field
  • :class:ResearchProblem — research problem addressed by a model
  • :class:MathematicalModel — central model entity with all related data
  • :class:QuantityOrQuantityKind — scalar quantity or quantity kind used in a model
  • :class:MathematicalFormulation — formula / equation belonging to a model
  • :class:Task — computational task derived from a model
  • fetch_formula_data — batch-fetch formula LaTeX and quantity info

MathematicalFormulation dataclass

Data Class For Formulation Item

Source code in MaRDMO/model/models.py
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
@dataclass  # pylint: disable=too-many-instance-attributes
class MathematicalFormulation:
    '''Data Class For Formulation Item'''
    reference: Optional[str] = None
    aliases: list[str] = field(default_factory=list)
    description_long: list[str] = field(default_factory=list)
    properties: dict[int, str] = field(default_factory=dict)
    formulas: list[str] = field(default_factory=list)
    symbols: list[str] = field(default_factory=list)
    contains_quantity: list[Relatant] = field(default_factory=list)
    assumes: list[Relatant] = field(default_factory=list)
    contains_formulation: list[Relatant] = field(default_factory=list)
    contains_assumption: list[Relatant] = field(default_factory=list)
    contains_boundary_condition: list[Relatant] = field(default_factory=list)
    contains_final_condition: list[Relatant] = field(default_factory=list)
    contains_initial_condition: list[Relatant] = field(default_factory=list)
    contains_constraint_condition: list[Relatant] = field(default_factory=list)
    contains_coupling_condition: list[Relatant] = field(default_factory=list)
    specialized_by: list[Relatant] = field(default_factory=list)
    specializes: list[Relatant] = field(default_factory=list)
    discretized_by: list[Relatant] = field(default_factory=list)
    discretizes: list[Relatant] = field(default_factory=list)
    approximated_by: list[Relatant] = field(default_factory=list)
    approximates: list[Relatant] = field(default_factory=list)
    linearized_by: list[Relatant] = field(default_factory=list)
    linearizes: list[Relatant] = field(default_factory=list)
    nondimensionalized_by: list[Relatant] = field(default_factory=list)
    nondimensionalizes: list[Relatant] = field(default_factory=list)
    has_weak_formulation: list[Relatant] = field(default_factory=list)
    is_weak_formulation_of: list[Relatant] = field(default_factory=list)
    similar_to: list[Relatant] = field(default_factory=list)
    publications: list[Relatant] = field(default_factory=list)


    @classmethod
    def from_query(cls, raw_data: dict) -> 'MathematicalFormulation':
        '''Generate Class Item From Query (single-item, backward-compatible).'''
        return cls.from_query_single(raw_data[0])

    @classmethod
    def from_query_batch(cls, raw_data: list) -> 'dict[str, MathematicalFormulation]':
        '''Parse a batch SPARQL result into {external_id: instance} dict.'''
        return {
            row['qid']['value']: cls.from_query_single(row)
            for row in raw_data
            if row.get('qid', {}).get('value')
        }

    @classmethod
    def from_query_single(cls, data: dict) -> 'MathematicalFormulation':
        '''Parse one SPARQL result row into a MathematicalFormulation instance.'''

        mathmoddb = get_mathmoddb()
        items = get_items()

        mathematical_formulation = {
            # Get Aliases
            'aliases': split_value(
                data = data,
                key = 'aliases'
            ),
            # Get Long Description(s)
            'description_long': split_value(
                data = data,
                key = 'description_long'
            ),
            # Get Properties
            'properties': {
                idx: [mathmoddb.get(key=prop)["url"]]
                for idx, prop in enumerate(data_properties_per_class['formulation'])
                if data.get(prop, {}).get('value') == 'True'
            },
            # Get Reference
            'reference': data.get('reference', {}).get('value'),
            # Get Assumption Relation(s)
            'assumes': split_value(
                data = data,
                key = 'assumes',
                transform = Relatant.from_query
            ),
            # Get Contains Formulation Relation(s)
            'contains_formulation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == ''
            ),
            # Get Contains Boundary Condition Relation(s)
            'contains_boundary_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["boundary condition"]}'
            ),
            # Get Contains Constraint Condition Relation(s)
            'contains_constraint_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["constraint"]}'
            ),
            # Get Contains Coupling Condition Relation(s)
            'contains_coupling_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["coupling condition"]}'
            ),
            # Get Contains Initial Condition Relation(s)
            'contains_initial_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["initial condition"]}'
            ),
            # Get Contains Final Condition Relation(s)
            'contains_final_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["final condition"]}'
            ),
            # Get Specialized By Relation(s)
            'specialized_by': split_value(
                data = data,
                key = 'specialized_by',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Specializes Relation(s)
            'specializes': split_value(
                data = data,
                key = 'specializes',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Approximated By Relation(s)
            'approximated_by': split_value(
                data = data,
                key = 'approximated_by',
                transform = Relatant.from_query
            ),
            # Get Approximates Relation(s)
            'approximates': split_value(
                data = data,
                key = 'approximates',
                transform = Relatant.from_query
            ),
            # Get Discretized By Relation(s)
            'discretized_by': split_value(
                data = data,
                key = 'discretized_by',
                transform = Relatant.from_query
            ),
            # Get Discretizes Relation(s)
            'discretizes': split_value(
                data = data,
                key = 'discretizes',
                transform = Relatant.from_query
            ),
            # Get Linearized By Relation(s)
            'linearized_by': split_value(
                data = data,
                key = 'linearized_by',
                transform = Relatant.from_query
            ),
            # Get Linearizes Relation(s)
            'linearizes': split_value(
                data = data,
                key = 'linearizes',
                transform = Relatant.from_query
            ),
            # Get Nondimensionalized By Relation(s)
            'nondimensionalized_by': split_value(
                data = data,
                key = 'nondimensionalized_by',
                transform = Relatant.from_query
            ),
            # Get Nondimesionalizes Relation(s)
            'nondimensionalizes': split_value(
                data = data,
                key = 'nondimensionalizes',
                transform = Relatant.from_query
            ),
            # Get Has Weak Formulation Relation(s)
            'has_weak_formulation': split_value(
                data = data,
                key = 'has_weak_formulation',
                transform = Relatant.from_query
            ),
            # Get Is Weak Formulation Of Relation(s)
            'is_weak_formulation_of': split_value(
                data = data,
                key = 'is_weak_formulation_of',
                transform = Relatant.from_query
            ),
            # Get Similar To Relation(s)
            'similar_to': split_value(
                data = data,
                key = 'similar_to',
                transform = Relatant.from_query
            ),
            # Get Publication(s)
            'publications': split_value(
                data = data,
                key = 'publication',
                transform = Relatant.from_query
            )
        }

        return cls(
            **mathematical_formulation
        )

from_query(raw_data) classmethod

Generate Class Item From Query (single-item, backward-compatible).

Source code in MaRDMO/model/models.py
833
834
835
836
@classmethod
def from_query(cls, raw_data: dict) -> 'MathematicalFormulation':
    '''Generate Class Item From Query (single-item, backward-compatible).'''
    return cls.from_query_single(raw_data[0])

from_query_batch(raw_data) classmethod

Parse a batch SPARQL result into {external_id: instance} dict.

Source code in MaRDMO/model/models.py
838
839
840
841
842
843
844
845
@classmethod
def from_query_batch(cls, raw_data: list) -> 'dict[str, MathematicalFormulation]':
    '''Parse a batch SPARQL result into {external_id: instance} dict.'''
    return {
        row['qid']['value']: cls.from_query_single(row)
        for row in raw_data
        if row.get('qid', {}).get('value')
    }

from_query_single(data) classmethod

Parse one SPARQL result row into a MathematicalFormulation instance.

Source code in MaRDMO/model/models.py
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
@classmethod
def from_query_single(cls, data: dict) -> 'MathematicalFormulation':
    '''Parse one SPARQL result row into a MathematicalFormulation instance.'''

    mathmoddb = get_mathmoddb()
    items = get_items()

    mathematical_formulation = {
        # Get Aliases
        'aliases': split_value(
            data = data,
            key = 'aliases'
        ),
        # Get Long Description(s)
        'description_long': split_value(
            data = data,
            key = 'description_long'
        ),
        # Get Properties
        'properties': {
            idx: [mathmoddb.get(key=prop)["url"]]
            for idx, prop in enumerate(data_properties_per_class['formulation'])
            if data.get(prop, {}).get('value') == 'True'
        },
        # Get Reference
        'reference': data.get('reference', {}).get('value'),
        # Get Assumption Relation(s)
        'assumes': split_value(
            data = data,
            key = 'assumes',
            transform = Relatant.from_query
        ),
        # Get Contains Formulation Relation(s)
        'contains_formulation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == ''
        ),
        # Get Contains Boundary Condition Relation(s)
        'contains_boundary_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["boundary condition"]}'
        ),
        # Get Contains Constraint Condition Relation(s)
        'contains_constraint_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["constraint"]}'
        ),
        # Get Contains Coupling Condition Relation(s)
        'contains_coupling_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["coupling condition"]}'
        ),
        # Get Contains Initial Condition Relation(s)
        'contains_initial_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["initial condition"]}'
        ),
        # Get Contains Final Condition Relation(s)
        'contains_final_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["final condition"]}'
        ),
        # Get Specialized By Relation(s)
        'specialized_by': split_value(
            data = data,
            key = 'specialized_by',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Specializes Relation(s)
        'specializes': split_value(
            data = data,
            key = 'specializes',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Approximated By Relation(s)
        'approximated_by': split_value(
            data = data,
            key = 'approximated_by',
            transform = Relatant.from_query
        ),
        # Get Approximates Relation(s)
        'approximates': split_value(
            data = data,
            key = 'approximates',
            transform = Relatant.from_query
        ),
        # Get Discretized By Relation(s)
        'discretized_by': split_value(
            data = data,
            key = 'discretized_by',
            transform = Relatant.from_query
        ),
        # Get Discretizes Relation(s)
        'discretizes': split_value(
            data = data,
            key = 'discretizes',
            transform = Relatant.from_query
        ),
        # Get Linearized By Relation(s)
        'linearized_by': split_value(
            data = data,
            key = 'linearized_by',
            transform = Relatant.from_query
        ),
        # Get Linearizes Relation(s)
        'linearizes': split_value(
            data = data,
            key = 'linearizes',
            transform = Relatant.from_query
        ),
        # Get Nondimensionalized By Relation(s)
        'nondimensionalized_by': split_value(
            data = data,
            key = 'nondimensionalized_by',
            transform = Relatant.from_query
        ),
        # Get Nondimesionalizes Relation(s)
        'nondimensionalizes': split_value(
            data = data,
            key = 'nondimensionalizes',
            transform = Relatant.from_query
        ),
        # Get Has Weak Formulation Relation(s)
        'has_weak_formulation': split_value(
            data = data,
            key = 'has_weak_formulation',
            transform = Relatant.from_query
        ),
        # Get Is Weak Formulation Of Relation(s)
        'is_weak_formulation_of': split_value(
            data = data,
            key = 'is_weak_formulation_of',
            transform = Relatant.from_query
        ),
        # Get Similar To Relation(s)
        'similar_to': split_value(
            data = data,
            key = 'similar_to',
            transform = Relatant.from_query
        ),
        # Get Publication(s)
        'publications': split_value(
            data = data,
            key = 'publication',
            transform = Relatant.from_query
        )
    }

    return cls(
        **mathematical_formulation
    )

MathematicalModel dataclass

Data Class For Mathematical Model Item

Source code in MaRDMO/model/models.py
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
@dataclass  # pylint: disable=too-many-instance-attributes
class MathematicalModel:
    '''Data Class For Mathematical Model Item'''
    aliases: list[str] = field(default_factory=list)
    description_long: list[str] = field(default_factory=list)
    properties: dict[int, str] = field(default_factory=dict)
    models: list[Relatant] = field(default_factory=list)
    assumes: list[Relatant] = field(default_factory=list)
    contains_formulation: list[Relatant] = field(default_factory=list)
    contains_boundary_condition: list[Relatant] = field(default_factory=list)
    contains_constraint_condition: list[Relatant] = field(default_factory=list)
    contains_coupling_condition: list[Relatant] = field(default_factory=list)
    contains_initial_condition: list[Relatant] = field(default_factory=list)
    contains_final_condition: list[Relatant] = field(default_factory=list)
    contains_analytical_solution: list[Relatant] = field(default_factory=list)
    contains_physical_law: list[Relatant] = field(default_factory=list)
    contains_computational_domain: list[Relatant] = field(default_factory=list)
    contains_constitutive_equation: list[Relatant] = field(default_factory=list)
    contains_weak_formulation: list[Relatant] = field(default_factory=list)
    contains_strong_formulation: list[Relatant] = field(default_factory=list)
    used_by: list[Relatant] = field(default_factory=list)
    specializes: list[Relatant] = field(default_factory=list)
    specialized_by: list[Relatant] = field(default_factory=list)
    approximates: list[Relatant] = field(default_factory=list)
    approximated_by: list[Relatant] = field(default_factory=list)
    contains_model: list[Relatant] = field(default_factory=list)
    contained_in_model: list[Relatant] = field(default_factory=list)
    discretized_by: list[Relatant] = field(default_factory=list)
    discretizes: list[Relatant] = field(default_factory=list)
    linearized_by: list[Relatant] = field(default_factory=list)
    linearizes: list[Relatant] = field(default_factory=list)
    has_weak_formulation: list[Relatant] = field(default_factory=list)
    is_weak_formulation_of: list[Relatant] = field(default_factory=list)
    similar_to: list[Relatant] = field(default_factory=list)
    publications: list[Relatant] = field(default_factory=list)

    @classmethod
    def from_query(cls, raw_data: dict) -> 'MathematicalModel':
        '''Generate Class Item From Query (single-item, backward-compatible).'''
        return cls.from_query_single(raw_data[0])

    @classmethod
    def from_query_batch(cls, raw_data: list) -> 'dict[str, MathematicalModel]':
        '''Parse a batch SPARQL result into {external_id: instance} dict.'''
        return {
            row['qid']['value']: cls.from_query_single(row)
            for row in raw_data
            if row.get('qid', {}).get('value')
        }

    @classmethod
    def from_query_single(cls, data: dict) -> 'MathematicalModel':
        '''Parse one SPARQL result row into a MathematicalModel instance.'''

        mathmoddb = get_mathmoddb()
        items = get_items()

        mathematical_model = {
            # Get Aliases
            'aliases': split_value(
                data = data,
                key = 'aliases'
            ),
            # Get Long Description(s)
            'description_long': split_value(
                data = data,
                key = 'description_long'
            ),
            # Get Properties
            'properties': {
                idx: [mathmoddb.get(key=prop)["url"]]
                for idx, prop in enumerate(data_properties_per_class['model'])
                if data.get(prop, {}).get('value') == 'True'
            },
            # Get Problem Relation(s)
            'models': split_value(
                data = data,
                key = 'models',
                transform = Relatant.from_query
            ),
            # Get Assumption Relation(s)
            'assumes': split_value(
                data = data,
                key = 'assumes',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Contains Formulation Relation(s)
            'contains_formulation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == ''
            ),
            # Get Contains Boundary Condition Relation(s)
            'contains_boundary_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["boundary condition"]}'
            ),
            # Get Contains Constraint Condition Relation(s)
            'contains_constraint_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["constraint"]}'
            ),
            # Get Contains Coupling Condition Relation(s)
            'contains_coupling_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["coupling condition"]}'
            ),
            # Get Contains Initial Condition Relation(s)
            'contains_initial_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["initial condition"]}'
            ),
            # Get Contains Final Condition Relation(s)
            'contains_final_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["final condition"]}'
            ),
            # Get Contains Analytical Solution Relation(s)
            'contains_analytical_solution': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["analytical solution"]}'
            ),
            # Get Contains Physical Law Relation(s)
            'contains_physical_law': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["physical law"]}'
            ),
            # Get Contains Computational Domain Relation(s)
            'contains_computational_domain': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = (
                    lambda item: item.qualifier == f'mardi:{items["computational domain"]}'
                )
            ),
            # Get Contains Constitutive Equation Relation(s)
            'contains_constitutive_equation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = (
                    lambda item: item.qualifier == f'mardi:{items["constitutive equation"]}'
                )
            ),
            # Get Contains Weak Formulation Relation(s)
            'contains_weak_formulation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["weak formulation"]}'
            ),
            # Get Contains Strong Formulation Relation(s)
            'contains_strong_formulation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["strong formulation"]}'
            ),
            # Get Task Relation(s)
            'used_by': split_value(
                data = data,
                key = 'used_by',
                transform = Relatant.from_query
            ),
            # Get Specialized By Relation(s)
            'specialized_by': split_value(
                data = data,
                key = 'specialized_by',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Specializes Relation(s)
            'specializes': split_value(
                data = data,
                key = 'specializes',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Approximated By Relation(s)
            'approximated_by': split_value(
                data = data,
                key = 'approximated_by',
                transform = Relatant.from_query
            ),
            # Get Approximates Relation(s)
            'approximates': split_value(
                data = data,
                key = 'approximates',
                transform = Relatant.from_query
            ),
            # Get Contained In Model Relation(s)
            'contained_in_model': split_value(
                data = data,
                key = 'contained_in_model',
                transform = Relatant.from_query
            ),
            # Get Contains Model Relation(s)
            'contains_model': split_value(
                data = data,
                key = 'contains_model',
                transform = Relatant.from_query
            ),
            # Get Discretized By Relation(s)
            'discretized_by': split_value(
                data = data,
                key = 'discretized_by',
                transform = Relatant.from_query
            ),
            # Get Discretizes Relation(s)
            'discretizes': split_value(
                data = data,
                key = 'discretizes',
                transform = Relatant.from_query
            ),
            # Get Linearized By Relation(s)
            'linearized_by': split_value(
                data = data,
                key = 'linearized_by',
                transform = Relatant.from_query
            ),
            # Get Linearizes Relation(s)
            'linearizes': split_value(
                data = data,
                key = 'linearizes',
                transform = Relatant.from_query
            ),
            # Get Has Weak Formulation Relation(s)
            'has_weak_formulation': split_value(
                data = data,
                key = 'has_weak_formulation',
                transform = Relatant.from_query
            ),
            # Get Is Weak Formulation Of Relation(s)
            'is_weak_formulation_of': split_value(
                data = data,
                key = 'is_weak_formulation_of',
                transform = Relatant.from_query
            ),
            # Get Similar To Relation(s)
            'similar_to': split_value(
                data = data,
                key = 'similar_to',
                transform = Relatant.from_query
            ),
            # Get Publication(s)
            'publications': split_value(
                data = data,
                key = 'publication',
                transform = Relatant.from_query
            )
        }

        return cls(
            **mathematical_model
        )

from_query(raw_data) classmethod

Generate Class Item From Query (single-item, backward-compatible).

Source code in MaRDMO/model/models.py
417
418
419
420
@classmethod
def from_query(cls, raw_data: dict) -> 'MathematicalModel':
    '''Generate Class Item From Query (single-item, backward-compatible).'''
    return cls.from_query_single(raw_data[0])

from_query_batch(raw_data) classmethod

Parse a batch SPARQL result into {external_id: instance} dict.

Source code in MaRDMO/model/models.py
422
423
424
425
426
427
428
429
@classmethod
def from_query_batch(cls, raw_data: list) -> 'dict[str, MathematicalModel]':
    '''Parse a batch SPARQL result into {external_id: instance} dict.'''
    return {
        row['qid']['value']: cls.from_query_single(row)
        for row in raw_data
        if row.get('qid', {}).get('value')
    }

from_query_single(data) classmethod

Parse one SPARQL result row into a MathematicalModel instance.

Source code in MaRDMO/model/models.py
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
@classmethod
def from_query_single(cls, data: dict) -> 'MathematicalModel':
    '''Parse one SPARQL result row into a MathematicalModel instance.'''

    mathmoddb = get_mathmoddb()
    items = get_items()

    mathematical_model = {
        # Get Aliases
        'aliases': split_value(
            data = data,
            key = 'aliases'
        ),
        # Get Long Description(s)
        'description_long': split_value(
            data = data,
            key = 'description_long'
        ),
        # Get Properties
        'properties': {
            idx: [mathmoddb.get(key=prop)["url"]]
            for idx, prop in enumerate(data_properties_per_class['model'])
            if data.get(prop, {}).get('value') == 'True'
        },
        # Get Problem Relation(s)
        'models': split_value(
            data = data,
            key = 'models',
            transform = Relatant.from_query
        ),
        # Get Assumption Relation(s)
        'assumes': split_value(
            data = data,
            key = 'assumes',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Contains Formulation Relation(s)
        'contains_formulation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == ''
        ),
        # Get Contains Boundary Condition Relation(s)
        'contains_boundary_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["boundary condition"]}'
        ),
        # Get Contains Constraint Condition Relation(s)
        'contains_constraint_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["constraint"]}'
        ),
        # Get Contains Coupling Condition Relation(s)
        'contains_coupling_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["coupling condition"]}'
        ),
        # Get Contains Initial Condition Relation(s)
        'contains_initial_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["initial condition"]}'
        ),
        # Get Contains Final Condition Relation(s)
        'contains_final_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["final condition"]}'
        ),
        # Get Contains Analytical Solution Relation(s)
        'contains_analytical_solution': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["analytical solution"]}'
        ),
        # Get Contains Physical Law Relation(s)
        'contains_physical_law': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["physical law"]}'
        ),
        # Get Contains Computational Domain Relation(s)
        'contains_computational_domain': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = (
                lambda item: item.qualifier == f'mardi:{items["computational domain"]}'
            )
        ),
        # Get Contains Constitutive Equation Relation(s)
        'contains_constitutive_equation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = (
                lambda item: item.qualifier == f'mardi:{items["constitutive equation"]}'
            )
        ),
        # Get Contains Weak Formulation Relation(s)
        'contains_weak_formulation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["weak formulation"]}'
        ),
        # Get Contains Strong Formulation Relation(s)
        'contains_strong_formulation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["strong formulation"]}'
        ),
        # Get Task Relation(s)
        'used_by': split_value(
            data = data,
            key = 'used_by',
            transform = Relatant.from_query
        ),
        # Get Specialized By Relation(s)
        'specialized_by': split_value(
            data = data,
            key = 'specialized_by',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Specializes Relation(s)
        'specializes': split_value(
            data = data,
            key = 'specializes',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Approximated By Relation(s)
        'approximated_by': split_value(
            data = data,
            key = 'approximated_by',
            transform = Relatant.from_query
        ),
        # Get Approximates Relation(s)
        'approximates': split_value(
            data = data,
            key = 'approximates',
            transform = Relatant.from_query
        ),
        # Get Contained In Model Relation(s)
        'contained_in_model': split_value(
            data = data,
            key = 'contained_in_model',
            transform = Relatant.from_query
        ),
        # Get Contains Model Relation(s)
        'contains_model': split_value(
            data = data,
            key = 'contains_model',
            transform = Relatant.from_query
        ),
        # Get Discretized By Relation(s)
        'discretized_by': split_value(
            data = data,
            key = 'discretized_by',
            transform = Relatant.from_query
        ),
        # Get Discretizes Relation(s)
        'discretizes': split_value(
            data = data,
            key = 'discretizes',
            transform = Relatant.from_query
        ),
        # Get Linearized By Relation(s)
        'linearized_by': split_value(
            data = data,
            key = 'linearized_by',
            transform = Relatant.from_query
        ),
        # Get Linearizes Relation(s)
        'linearizes': split_value(
            data = data,
            key = 'linearizes',
            transform = Relatant.from_query
        ),
        # Get Has Weak Formulation Relation(s)
        'has_weak_formulation': split_value(
            data = data,
            key = 'has_weak_formulation',
            transform = Relatant.from_query
        ),
        # Get Is Weak Formulation Of Relation(s)
        'is_weak_formulation_of': split_value(
            data = data,
            key = 'is_weak_formulation_of',
            transform = Relatant.from_query
        ),
        # Get Similar To Relation(s)
        'similar_to': split_value(
            data = data,
            key = 'similar_to',
            transform = Relatant.from_query
        ),
        # Get Publication(s)
        'publications': split_value(
            data = data,
            key = 'publication',
            transform = Relatant.from_query
        )
    }

    return cls(
        **mathematical_model
    )

QuantityOrQuantityKind dataclass

Data Class For Quantity [Kind] Item

Source code in MaRDMO/model/models.py
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
@dataclass  # pylint: disable=too-many-instance-attributes
class QuantityOrQuantityKind:
    '''Data Class For Quantity [Kind] Item'''
    aliases: list[str] = field(default_factory=list)
    description_long: list[str] = field(default_factory=list)
    reference: dict[int, list[str]] = field(default_factory=dict)
    qclass: Optional[str] = None
    properties: dict[int, str] = field(default_factory=dict)
    formulas: list[str] = field(default_factory=list)
    symbols: list[str] = field(default_factory=list)
    contains_quantity: list[Relatant] = field(default_factory=list)
    specialized_by: list[Relatant] = field(default_factory=list)
    specializes: list[Relatant] = field(default_factory=list)
    approximated_by: list[Relatant] = field(default_factory=list)
    approximates: list[Relatant] = field(default_factory=list)
    discretized_by: list[Relatant] = field(default_factory=list)
    discretizes: list[Relatant] = field(default_factory=list)
    linearized_by: list[Relatant] = field(default_factory=list)
    linearizes: list[Relatant] = field(default_factory=list)
    nondimensionalized_by: list[Relatant] = field(default_factory=list)
    nondimensionalizes: list[Relatant] = field(default_factory=list)
    similar_to: list[Relatant] = field(default_factory=list)
    publications: list[Relatant] = field(default_factory=list)

    @classmethod
    def from_query(cls, raw_data: dict) -> 'QuantityOrQuantityKind':
        '''Generate Class Item From Query (single-item, backward-compatible).'''
        return cls.from_query_single(raw_data[0])

    @classmethod
    def from_query_batch(cls, raw_data: list) -> 'dict[str, QuantityOrQuantityKind]':
        '''Parse a batch SPARQL result into {external_id: instance} dict.'''
        return {
            row['qid']['value']: cls.from_query_single(row)
            for row in raw_data
            if row.get('qid', {}).get('value')
        }

    @classmethod
    def from_query_single(cls, data: dict) -> 'QuantityOrQuantityKind':
        '''Parse one SPARQL result row into a QuantityOrQuantityKind instance.'''

        mathmoddb = get_mathmoddb()
        options = get_options()

        quantity = {
            # Get Aliases
            'aliases': split_value(
                data = data,
                key = 'aliases'
            ),
            # Get Long Description(s)
            'description_long': split_value(
                data = data,
                key = 'description_long'
            ),
            # Get Reference
            'reference': {
                idx: [options[prop], data[prop]['value']]
                for idx, prop in enumerate(qudt_reference_ids)
                if data.get(prop, {}).get('value')
            },
            # Get Quantity or Quantity Kind Class
            'qclass': data.get('class', {}).get('value'),
            # Get Properties
            'properties': {
                idx: [mathmoddb.get(key=prop)["url"]]
                for idx, prop in enumerate(data_properties_per_class['quantity'])
                if data.get(prop, {}).get('value') == 'True'
            },
            # Get Specialized By Relation(s)
            'specialized_by': split_value(
                data = data,
                key = 'specialized_by',
                transform = RelatantWithClass.from_query
            ),
            # Get Specializes Relation(s)
            'specializes': split_value(
                data = data,
                key = 'specializes',
                transform = RelatantWithClass.from_query
            ),
            # Get Approximated By Relation(s)
            'approximated_by': split_value(
                data = data,
                key = 'approximated_by',
                transform = RelatantWithClass.from_query
            ),
            # Get Approximates Relation(s)
            'approximates': split_value(
                data = data,
                key = 'approximates',
                transform = RelatantWithClass.from_query
            ),
            # Get Discretized By Relation(s)
            'discretized_by': split_value(
                data = data,
                key = 'discretized_by',
                transform = RelatantWithClass.from_query
            ),
            # Get Discretizes Relation(s)
            'discretizes': split_value(
                data = data,
                key = 'discretizes',
                transform = RelatantWithClass.from_query
            ),
            # Get Linearized By Relation(s)
            'linearized_by': split_value(
                data = data,
                key = 'linearized_by',
                transform = RelatantWithClass.from_query
            ),
            # Get Linearizes Relation(s)
            'linearizes': split_value(
                data = data,
                key = 'linearizes',
                transform = RelatantWithClass.from_query
            ),
            # Get Nondimesionalized By Relation(s)
            'nondimensionalized_by': split_value(
                data = data,
                key = 'nondimensionalized_by',
                transform = RelatantWithClass.from_query
            ),
            # Get Nondimensionalizes Relation(s)
            'nondimensionalizes': split_value(
                data = data,
                key = 'nondimensionalizes',
                transform = RelatantWithClass.from_query
            ),
            # Get Similar To Relation(s)
            'similar_to': split_value(
                data = data,
                key = 'similar_to',
                transform = RelatantWithClass.from_query
            ),
            # Get Publication(s)
            'publications': split_value(
                data = data,
                key = 'publication',
                transform = Relatant.from_query
            )
        }

        return cls(
            **quantity
        )

from_query(raw_data) classmethod

Generate Class Item From Query (single-item, backward-compatible).

Source code in MaRDMO/model/models.py
675
676
677
678
@classmethod
def from_query(cls, raw_data: dict) -> 'QuantityOrQuantityKind':
    '''Generate Class Item From Query (single-item, backward-compatible).'''
    return cls.from_query_single(raw_data[0])

from_query_batch(raw_data) classmethod

Parse a batch SPARQL result into {external_id: instance} dict.

Source code in MaRDMO/model/models.py
680
681
682
683
684
685
686
687
@classmethod
def from_query_batch(cls, raw_data: list) -> 'dict[str, QuantityOrQuantityKind]':
    '''Parse a batch SPARQL result into {external_id: instance} dict.'''
    return {
        row['qid']['value']: cls.from_query_single(row)
        for row in raw_data
        if row.get('qid', {}).get('value')
    }

from_query_single(data) classmethod

Parse one SPARQL result row into a QuantityOrQuantityKind instance.

Source code in MaRDMO/model/models.py
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
@classmethod
def from_query_single(cls, data: dict) -> 'QuantityOrQuantityKind':
    '''Parse one SPARQL result row into a QuantityOrQuantityKind instance.'''

    mathmoddb = get_mathmoddb()
    options = get_options()

    quantity = {
        # Get Aliases
        'aliases': split_value(
            data = data,
            key = 'aliases'
        ),
        # Get Long Description(s)
        'description_long': split_value(
            data = data,
            key = 'description_long'
        ),
        # Get Reference
        'reference': {
            idx: [options[prop], data[prop]['value']]
            for idx, prop in enumerate(qudt_reference_ids)
            if data.get(prop, {}).get('value')
        },
        # Get Quantity or Quantity Kind Class
        'qclass': data.get('class', {}).get('value'),
        # Get Properties
        'properties': {
            idx: [mathmoddb.get(key=prop)["url"]]
            for idx, prop in enumerate(data_properties_per_class['quantity'])
            if data.get(prop, {}).get('value') == 'True'
        },
        # Get Specialized By Relation(s)
        'specialized_by': split_value(
            data = data,
            key = 'specialized_by',
            transform = RelatantWithClass.from_query
        ),
        # Get Specializes Relation(s)
        'specializes': split_value(
            data = data,
            key = 'specializes',
            transform = RelatantWithClass.from_query
        ),
        # Get Approximated By Relation(s)
        'approximated_by': split_value(
            data = data,
            key = 'approximated_by',
            transform = RelatantWithClass.from_query
        ),
        # Get Approximates Relation(s)
        'approximates': split_value(
            data = data,
            key = 'approximates',
            transform = RelatantWithClass.from_query
        ),
        # Get Discretized By Relation(s)
        'discretized_by': split_value(
            data = data,
            key = 'discretized_by',
            transform = RelatantWithClass.from_query
        ),
        # Get Discretizes Relation(s)
        'discretizes': split_value(
            data = data,
            key = 'discretizes',
            transform = RelatantWithClass.from_query
        ),
        # Get Linearized By Relation(s)
        'linearized_by': split_value(
            data = data,
            key = 'linearized_by',
            transform = RelatantWithClass.from_query
        ),
        # Get Linearizes Relation(s)
        'linearizes': split_value(
            data = data,
            key = 'linearizes',
            transform = RelatantWithClass.from_query
        ),
        # Get Nondimesionalized By Relation(s)
        'nondimensionalized_by': split_value(
            data = data,
            key = 'nondimensionalized_by',
            transform = RelatantWithClass.from_query
        ),
        # Get Nondimensionalizes Relation(s)
        'nondimensionalizes': split_value(
            data = data,
            key = 'nondimensionalizes',
            transform = RelatantWithClass.from_query
        ),
        # Get Similar To Relation(s)
        'similar_to': split_value(
            data = data,
            key = 'similar_to',
            transform = RelatantWithClass.from_query
        ),
        # Get Publication(s)
        'publications': split_value(
            data = data,
            key = 'publication',
            transform = Relatant.from_query
        )
    }

    return cls(
        **quantity
    )

RelatantWithQualifier dataclass

Data Class For Relatant Items With Qualifier

Source code in MaRDMO/model/models.py
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
@dataclass
class RelatantWithQualifier:
    '''Data Class For Relatant Items With Qualifier'''
    id: Optional[str]
    label: Optional[str]
    description: Optional[str]
    qualifier: Optional[str]
    order: Optional[str]

    @classmethod
    def from_query(cls, raw: str) -> 'RelatantWithQualifier':
        '''Parse a delimited SPARQL result string into a RelatantWithQualifier instance.

        Args:
            raw: Delimited string with four ``||``-separated fields (identifier,
                 label, description, qualifier) and an optional ``>|<``-separated
                 order suffix.

        Returns:
            RelatantWithQualifier instance populated from the parsed fields.
        '''
        if ">|<" in raw:
            raw, order = raw.split(" >|< ")
        else:
            order = None
        identifier, label, description, qualifier = raw.split(" || ", 3)
        return cls(
            id = identifier,
            label = label,
            description = description,
            qualifier = qualifier,
            order = order
        )

from_query(raw) classmethod

Parse a delimited SPARQL result string into a RelatantWithQualifier instance.

Parameters:

Name Type Description Default
raw str

Delimited string with four ||-separated fields (identifier, label, description, qualifier) and an optional >|<-separated order suffix.

required

Returns:

Type Description
RelatantWithQualifier

RelatantWithQualifier instance populated from the parsed fields.

Source code in MaRDMO/model/models.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
@classmethod
def from_query(cls, raw: str) -> 'RelatantWithQualifier':
    '''Parse a delimited SPARQL result string into a RelatantWithQualifier instance.

    Args:
        raw: Delimited string with four ``||``-separated fields (identifier,
             label, description, qualifier) and an optional ``>|<``-separated
             order suffix.

    Returns:
        RelatantWithQualifier instance populated from the parsed fields.
    '''
    if ">|<" in raw:
        raw, order = raw.split(" >|< ")
    else:
        order = None
    identifier, label, description, qualifier = raw.split(" || ", 3)
    return cls(
        id = identifier,
        label = label,
        description = description,
        qualifier = qualifier,
        order = order
    )

ResearchField dataclass

Data Class For Research Field Item

Source code in MaRDMO/model/models.py
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
@dataclass
class ResearchField:
    '''Data Class For Research Field Item'''
    aliases: list[str] = field(default_factory=list)
    description_long: list[str] = field(default_factory=list)
    specialized_by: list[Relatant] = field(default_factory=list)
    specializes: list[Relatant] = field(default_factory=list)
    similar_to: list[Relatant] = field(default_factory=list)
    publications: list[Relatant] = field(default_factory=list)

    @classmethod
    def from_query(cls, raw_data: dict) -> 'ResearchField':
        '''Generate Class Item From Query (single-item, backward-compatible).'''
        return cls.from_query_single(raw_data[0])

    @classmethod
    def from_query_batch(cls, raw_data: list) -> 'dict[str, ResearchField]':
        '''Parse a batch SPARQL result into {external_id: instance} dict.'''
        return {
            row['qid']['value']: cls.from_query_single(row)
            for row in raw_data
            if row.get('qid', {}).get('value')
        }

    @classmethod
    def from_query_single(cls, data: dict) -> 'ResearchField':
        '''Parse one SPARQL result row into a ResearchField instance.'''

        research_field = {
            # Get Aliases
            'aliases': split_value(
                data = data,
                key = 'aliases'
            ),
            # Get Long Description(s)
            'description_long': split_value(
                data = data,
                key = 'description_long'
            ),
            # Get Specialized By Relation(s)
            'specialized_by': split_value(
                data = data,
                key = 'specialized_by',
                transform = Relatant.from_query
            ),
            # Get Specializes Relation(s)
            'specializes': split_value(
                data = data,
                key = 'specializes',
                transform = Relatant.from_query
            ),
            # Get Similar To Relation(s)
            'similar_to': split_value(
                data = data,
                key = 'similar_to',
                transform = Relatant.from_query
            ),
            # Get Publication(s)
            'publications': split_value(
                data = data,
                key = 'publication',
                transform = Relatant.from_query
            )
        }

        return cls(
            **research_field
        )

from_query(raw_data) classmethod

Generate Class Item From Query (single-item, backward-compatible).

Source code in MaRDMO/model/models.py
246
247
248
249
@classmethod
def from_query(cls, raw_data: dict) -> 'ResearchField':
    '''Generate Class Item From Query (single-item, backward-compatible).'''
    return cls.from_query_single(raw_data[0])

from_query_batch(raw_data) classmethod

Parse a batch SPARQL result into {external_id: instance} dict.

Source code in MaRDMO/model/models.py
251
252
253
254
255
256
257
258
@classmethod
def from_query_batch(cls, raw_data: list) -> 'dict[str, ResearchField]':
    '''Parse a batch SPARQL result into {external_id: instance} dict.'''
    return {
        row['qid']['value']: cls.from_query_single(row)
        for row in raw_data
        if row.get('qid', {}).get('value')
    }

from_query_single(data) classmethod

Parse one SPARQL result row into a ResearchField instance.

Source code in MaRDMO/model/models.py
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
@classmethod
def from_query_single(cls, data: dict) -> 'ResearchField':
    '''Parse one SPARQL result row into a ResearchField instance.'''

    research_field = {
        # Get Aliases
        'aliases': split_value(
            data = data,
            key = 'aliases'
        ),
        # Get Long Description(s)
        'description_long': split_value(
            data = data,
            key = 'description_long'
        ),
        # Get Specialized By Relation(s)
        'specialized_by': split_value(
            data = data,
            key = 'specialized_by',
            transform = Relatant.from_query
        ),
        # Get Specializes Relation(s)
        'specializes': split_value(
            data = data,
            key = 'specializes',
            transform = Relatant.from_query
        ),
        # Get Similar To Relation(s)
        'similar_to': split_value(
            data = data,
            key = 'similar_to',
            transform = Relatant.from_query
        ),
        # Get Publication(s)
        'publications': split_value(
            data = data,
            key = 'publication',
            transform = Relatant.from_query
        )
    }

    return cls(
        **research_field
    )

ResearchProblem dataclass

Data Class For Research Problem Item

Source code in MaRDMO/model/models.py
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
@dataclass
class ResearchProblem:
    '''Data Class For Research Problem Item'''
    aliases: list[str] = field(default_factory=list)
    description_long: list[str] = field(default_factory=list)
    contained_in_field: list[Relatant] = field(default_factory=list)
    specialized_by: list[Relatant] = field(default_factory=list)
    specializes: list[Relatant] = field(default_factory=list)
    similar_to: list[Relatant] = field(default_factory=list)
    publications: list[Relatant] = field(default_factory=list)

    @classmethod
    def from_query(cls, raw_data: dict) -> 'ResearchProblem':
        '''Generate Class Item From Query (single-item, backward-compatible).'''
        return cls.from_query_single(raw_data[0])

    @classmethod
    def from_query_batch(cls, raw_data: list) -> 'dict[str, ResearchProblem]':
        '''Parse a batch SPARQL result into {external_id: instance} dict.'''
        return {
            row['qid']['value']: cls.from_query_single(row)
            for row in raw_data
            if row.get('qid', {}).get('value')
        }

    @classmethod
    def from_query_single(cls, data: dict) -> 'ResearchProblem':
        '''Parse one SPARQL result row into a ResearchProblem instance.'''

        research_problem = {
            # Get Aliases
            'aliases': split_value(
                data = data,
                key = 'aliases'
            ),
            # Get Long Description(s)
            'description_long': split_value(
                data = data,
                key = 'description_long'
            ),
            # Get Field Relation(s)
            'contained_in_field': split_value(
                data = data,
                key = 'contained_in_field',
                transform = Relatant.from_query
            ),
            # Get Specialized By Relation(s)
            'specialized_by': split_value(
                data = data,
                key = 'specialized_by',
                transform = Relatant.from_query
            ),
            # Get Specializes Relation(s)
            'specializes': split_value(
                data = data,
                key = 'specializes',
                transform = Relatant.from_query
            ),
            # Get Similar To Relation(s)
            'similar_to': split_value(
                data = data,
                key = 'similar_to',
                transform = Relatant.from_query
            ),
            # Get Publication(s)
            'publications': split_value(
                data = data,
                key = 'publication',
                transform = Relatant.from_query
            )
        }

        return cls(
            **research_problem
        )

from_query(raw_data) classmethod

Generate Class Item From Query (single-item, backward-compatible).

Source code in MaRDMO/model/models.py
316
317
318
319
@classmethod
def from_query(cls, raw_data: dict) -> 'ResearchProblem':
    '''Generate Class Item From Query (single-item, backward-compatible).'''
    return cls.from_query_single(raw_data[0])

from_query_batch(raw_data) classmethod

Parse a batch SPARQL result into {external_id: instance} dict.

Source code in MaRDMO/model/models.py
321
322
323
324
325
326
327
328
@classmethod
def from_query_batch(cls, raw_data: list) -> 'dict[str, ResearchProblem]':
    '''Parse a batch SPARQL result into {external_id: instance} dict.'''
    return {
        row['qid']['value']: cls.from_query_single(row)
        for row in raw_data
        if row.get('qid', {}).get('value')
    }

from_query_single(data) classmethod

Parse one SPARQL result row into a ResearchProblem instance.

Source code in MaRDMO/model/models.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
@classmethod
def from_query_single(cls, data: dict) -> 'ResearchProblem':
    '''Parse one SPARQL result row into a ResearchProblem instance.'''

    research_problem = {
        # Get Aliases
        'aliases': split_value(
            data = data,
            key = 'aliases'
        ),
        # Get Long Description(s)
        'description_long': split_value(
            data = data,
            key = 'description_long'
        ),
        # Get Field Relation(s)
        'contained_in_field': split_value(
            data = data,
            key = 'contained_in_field',
            transform = Relatant.from_query
        ),
        # Get Specialized By Relation(s)
        'specialized_by': split_value(
            data = data,
            key = 'specialized_by',
            transform = Relatant.from_query
        ),
        # Get Specializes Relation(s)
        'specializes': split_value(
            data = data,
            key = 'specializes',
            transform = Relatant.from_query
        ),
        # Get Similar To Relation(s)
        'similar_to': split_value(
            data = data,
            key = 'similar_to',
            transform = Relatant.from_query
        ),
        # Get Publication(s)
        'publications': split_value(
            data = data,
            key = 'publication',
            transform = Relatant.from_query
        )
    }

    return cls(
        **research_problem
    )

Task dataclass

Data Class For Task Item

Source code in MaRDMO/model/models.py
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
@dataclass  # pylint: disable=too-many-instance-attributes
class Task:
    '''Data Class For Task Item'''
    aliases: list[str] = field(default_factory=list)
    description_long: list[str] = field(default_factory=list)
    properties: dict[int, str] = field(default_factory=dict)
    assumes: list[Relatant] = field(default_factory=list)
    contains_formulation: list[Relatant] = field(default_factory=list)
    contains_boundary_condition: list[Relatant] = field(default_factory=list)
    contains_final_condition: list[Relatant] = field(default_factory=list)
    contains_initial_condition: list[Relatant] = field(default_factory=list)
    contains_constraint_condition: list[Relatant] = field(default_factory=list)
    contains_coupling_condition: list[Relatant] = field(default_factory=list)
    contains_analytical_solution: list[Relatant] = field(default_factory=list)
    contains_physical_law: list[Relatant] = field(default_factory=list)
    contains_computational_domain: list[Relatant] = field(default_factory=list)
    contains_constitutive_equation: list[Relatant] = field(default_factory=list)
    contains_weak_formulation: list[Relatant] = field(default_factory=list)
    contains_strong_formulation: list[Relatant] = field(default_factory=list)
    contains_input: list[Relatant] = field(default_factory=list)
    contains_output: list[Relatant] = field(default_factory=list)
    contains_objective: list[Relatant] = field(default_factory=list)
    contains_parameter: list[Relatant] = field(default_factory=list)
    contains_constant: list[Relatant] = field(default_factory=list)
    specializes: list[Relatant] = field(default_factory=list)
    specialized_by: list[Relatant] = field(default_factory=list)
    approximates: list[Relatant] = field(default_factory=list)
    approximated_by: list[Relatant] = field(default_factory=list)
    contains_task: list[Relatant] = field(default_factory=list)
    contained_in_task: list[Relatant] = field(default_factory=list)
    discretized_by: list[Relatant] = field(default_factory=list)
    discretizes: list[Relatant] = field(default_factory=list)
    linearized_by: list[Relatant] = field(default_factory=list)
    linearizes: list[Relatant] = field(default_factory=list)
    similar_to: list[Relatant] = field(default_factory=list)
    publications: list[Relatant] = field(default_factory=list)

    @classmethod
    def from_query(cls, raw_data: dict) -> 'Task':
        '''Generate Class Item From Query (single-item, backward-compatible).'''
        return cls.from_query_single(raw_data[0])

    @classmethod
    def from_query_batch(cls, raw_data: list) -> 'dict[str, Task]':
        '''Parse a batch SPARQL result into {external_id: instance} dict.'''
        return {
            row['qid']['value']: cls.from_query_single(row)
            for row in raw_data
            if row.get('qid', {}).get('value')
        }

    @classmethod
    def from_query_single(cls, data: dict) -> 'Task':
        '''Parse one SPARQL result row into a Task instance.'''

        mathmoddb = get_mathmoddb()
        items = get_items()

        task = {
            # Get Aliases
            'aliases': split_value(
                data = data,
                key = 'aliases'
            ),
            # Get Long Description(s)
            'description_long': split_value(
                data = data,
                key = 'description_long'
            ),
            # Get Properties
            'properties': {
                idx: [mathmoddb.get(key=prop)["url"]]
                for idx, prop in enumerate(data_properties_per_class['task'])
                if data.get(prop, {}).get('value') == 'True'
            },
            # Get Assumption Relation(s)
            'assumes': split_value(
                data = data,
                key = 'assumes',
                transform = Relatant.from_query
            ),
            # Get Contains Formulation Relation(s)
            'contains_formulation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == ''
            ),
            # Get Contains Boundary Condition Relation(s)
            'contains_boundary_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["boundary condition"]}'
            ),
            # Get Contains Constraint Condition Relation(s)
            'contains_constraint_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["constraint"]}'
            ),
            # Get Contains Coupling Condition Relation(s)
            'contains_coupling_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["coupling condition"]}'
            ),
            # Get Contains Initial Condition Relation(s)
            'contains_initial_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["initial condition"]}'
            ),
            # Get Contains Final Condition Relation(s)
            'contains_final_condition': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["final condition"]}'
            ),
            # Get Contains Analytical Solution Relation(s)
            'contains_analytical_solution': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["analytical solution"]}'
            ),
            # Get Contains Physical Law Relation(s)
            'contains_physical_law': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["physical law"]}'
            ),
            # Get Contains Computational Domain Relation(s)
            'contains_computational_domain': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = (
                    lambda item: item.qualifier == f'mardi:{items["computational domain"]}'
                )
            ),
            # Get Contains Constitutive Equation Relation(s)
            'contains_constitutive_equation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = (
                    lambda item: item.qualifier == f'mardi:{items["constitutive equation"]}'
                )
            ),
            # Get Contains Weak Formulation Relation(s)
            'contains_weak_formulation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["weak formulation"]}'
            ),
            # Get Contains Strong Formulation Relation(s)
            'contains_strong_formulation': split_value(
                data = data,
                key = 'contains_formulation',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["strong formulation"]}'
            ),
            # Get Contains Input Relation(s)
            'contains_input': split_value(
                data = data,
                key = 'contains_quantity',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["input"]}'
            ),
            # Get Contains Output Relation(s)
            'contains_output': split_value(
                data = data,
                key = 'contains_quantity',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["output"]}'
            ),
            # Get Contains Objective Relation(s)
            'contains_objective': split_value(
                data = data,
                key = 'contains_quantity',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["objective function"]}'
            ),
            # Get Contains Parameter Relation(s)
            'contains_parameter': split_value(
                data = data,
                key = 'contains_quantity',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["parameter"]}'
            ),
            # Get Contains Constant Relation(s)
            'contains_constant': split_value(
                data = data,
                key = 'contains_quantity',
                transform = RelatantWithQualifier.from_query,
                object_role = lambda item: item.qualifier == f'mardi:{items["constant"]}'
            ),
            # Get Specialized By Relation(s)
            'specialized_by': split_value(
                data = data,
                key = 'specialized_by',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Specializes Relation(s)
            'specializes': split_value(
                data = data,
                key = 'specializes',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Approximated By Relation(s)
            'approximated_by': split_value(
                data = data,
                key = 'approximated_by',
                transform = Relatant.from_query
            ),
            # Get Approximates Relation(s)
            'approximates': split_value(
                data = data,
                key = 'approximates',
                transform = Relatant.from_query
            ),
            # Get Contained In Relation(s)
            'contained_in_task': split_value(
                data = data,
                key = 'contained_in_task',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Contains Relation(s)
            'contains_task': split_value(
                data = data,
                key = 'contains_task',
                transform = RelatantWithQualifier.from_query
            ),
            # Get Discretized By Relation(s)
            'discretized_by': split_value(
                data = data,
                key = 'discretized_by',
                transform = Relatant.from_query
            ),
            # Get Discretizes Relation(s)
            'discretizes': split_value(
                data = data,
                key = 'discretizes',
                transform = Relatant.from_query
            ),
            # Get Linearized By Relation(s)
            'linearized_by': split_value(
                data = data,
                key = 'linearized_by',
                transform = Relatant.from_query
            ),
            # Get Linearizes Relation(s)
            'linearizes': split_value(
                data = data,
                key = 'linearizes',
                transform = Relatant.from_query
            ),
            # Get Similar To Relation(s)
            'similar_to': split_value(
                data = data,
                key = 'similar_to',
                transform = Relatant.from_query
            ),
            # Get Publication(s)
            'publications': split_value(
                data = data,
                key = 'publication',
                transform = Relatant.from_query
            )
        }

        return cls(
            **task
            )

from_query(raw_data) classmethod

Generate Class Item From Query (single-item, backward-compatible).

Source code in MaRDMO/model/models.py
1048
1049
1050
1051
@classmethod
def from_query(cls, raw_data: dict) -> 'Task':
    '''Generate Class Item From Query (single-item, backward-compatible).'''
    return cls.from_query_single(raw_data[0])

from_query_batch(raw_data) classmethod

Parse a batch SPARQL result into {external_id: instance} dict.

Source code in MaRDMO/model/models.py
1053
1054
1055
1056
1057
1058
1059
1060
@classmethod
def from_query_batch(cls, raw_data: list) -> 'dict[str, Task]':
    '''Parse a batch SPARQL result into {external_id: instance} dict.'''
    return {
        row['qid']['value']: cls.from_query_single(row)
        for row in raw_data
        if row.get('qid', {}).get('value')
    }

from_query_single(data) classmethod

Parse one SPARQL result row into a Task instance.

Source code in MaRDMO/model/models.py
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
@classmethod
def from_query_single(cls, data: dict) -> 'Task':
    '''Parse one SPARQL result row into a Task instance.'''

    mathmoddb = get_mathmoddb()
    items = get_items()

    task = {
        # Get Aliases
        'aliases': split_value(
            data = data,
            key = 'aliases'
        ),
        # Get Long Description(s)
        'description_long': split_value(
            data = data,
            key = 'description_long'
        ),
        # Get Properties
        'properties': {
            idx: [mathmoddb.get(key=prop)["url"]]
            for idx, prop in enumerate(data_properties_per_class['task'])
            if data.get(prop, {}).get('value') == 'True'
        },
        # Get Assumption Relation(s)
        'assumes': split_value(
            data = data,
            key = 'assumes',
            transform = Relatant.from_query
        ),
        # Get Contains Formulation Relation(s)
        'contains_formulation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == ''
        ),
        # Get Contains Boundary Condition Relation(s)
        'contains_boundary_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["boundary condition"]}'
        ),
        # Get Contains Constraint Condition Relation(s)
        'contains_constraint_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["constraint"]}'
        ),
        # Get Contains Coupling Condition Relation(s)
        'contains_coupling_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["coupling condition"]}'
        ),
        # Get Contains Initial Condition Relation(s)
        'contains_initial_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["initial condition"]}'
        ),
        # Get Contains Final Condition Relation(s)
        'contains_final_condition': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["final condition"]}'
        ),
        # Get Contains Analytical Solution Relation(s)
        'contains_analytical_solution': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["analytical solution"]}'
        ),
        # Get Contains Physical Law Relation(s)
        'contains_physical_law': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["physical law"]}'
        ),
        # Get Contains Computational Domain Relation(s)
        'contains_computational_domain': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = (
                lambda item: item.qualifier == f'mardi:{items["computational domain"]}'
            )
        ),
        # Get Contains Constitutive Equation Relation(s)
        'contains_constitutive_equation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = (
                lambda item: item.qualifier == f'mardi:{items["constitutive equation"]}'
            )
        ),
        # Get Contains Weak Formulation Relation(s)
        'contains_weak_formulation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["weak formulation"]}'
        ),
        # Get Contains Strong Formulation Relation(s)
        'contains_strong_formulation': split_value(
            data = data,
            key = 'contains_formulation',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["strong formulation"]}'
        ),
        # Get Contains Input Relation(s)
        'contains_input': split_value(
            data = data,
            key = 'contains_quantity',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["input"]}'
        ),
        # Get Contains Output Relation(s)
        'contains_output': split_value(
            data = data,
            key = 'contains_quantity',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["output"]}'
        ),
        # Get Contains Objective Relation(s)
        'contains_objective': split_value(
            data = data,
            key = 'contains_quantity',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["objective function"]}'
        ),
        # Get Contains Parameter Relation(s)
        'contains_parameter': split_value(
            data = data,
            key = 'contains_quantity',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["parameter"]}'
        ),
        # Get Contains Constant Relation(s)
        'contains_constant': split_value(
            data = data,
            key = 'contains_quantity',
            transform = RelatantWithQualifier.from_query,
            object_role = lambda item: item.qualifier == f'mardi:{items["constant"]}'
        ),
        # Get Specialized By Relation(s)
        'specialized_by': split_value(
            data = data,
            key = 'specialized_by',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Specializes Relation(s)
        'specializes': split_value(
            data = data,
            key = 'specializes',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Approximated By Relation(s)
        'approximated_by': split_value(
            data = data,
            key = 'approximated_by',
            transform = Relatant.from_query
        ),
        # Get Approximates Relation(s)
        'approximates': split_value(
            data = data,
            key = 'approximates',
            transform = Relatant.from_query
        ),
        # Get Contained In Relation(s)
        'contained_in_task': split_value(
            data = data,
            key = 'contained_in_task',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Contains Relation(s)
        'contains_task': split_value(
            data = data,
            key = 'contains_task',
            transform = RelatantWithQualifier.from_query
        ),
        # Get Discretized By Relation(s)
        'discretized_by': split_value(
            data = data,
            key = 'discretized_by',
            transform = Relatant.from_query
        ),
        # Get Discretizes Relation(s)
        'discretizes': split_value(
            data = data,
            key = 'discretizes',
            transform = Relatant.from_query
        ),
        # Get Linearized By Relation(s)
        'linearized_by': split_value(
            data = data,
            key = 'linearized_by',
            transform = Relatant.from_query
        ),
        # Get Linearizes Relation(s)
        'linearizes': split_value(
            data = data,
            key = 'linearizes',
            transform = Relatant.from_query
        ),
        # Get Similar To Relation(s)
        'similar_to': split_value(
            data = data,
            key = 'similar_to',
            transform = Relatant.from_query
        ),
        # Get Publication(s)
        'publications': split_value(
            data = data,
            key = 'publication',
            transform = Relatant.from_query
        )
    }

    return cls(
        **task
        )

fetch_formula_data(qids)

Fetch defining formula and in-defining-formula data via the wbgetentities API.

Parameters:

Name Type Description Default
qids list

List of raw QIDs such as ['Q123', 'Q456'] (without mardi: prefix).

required

Returns:

Type Description
dict

Dict mapping each QID to a result dict with keys:

dict

formulas (list[str]), symbols (list[str]),

dict

and contains_quantity (list[Relatant]).

dict

Returns an empty dict if qids is empty.

Source code in MaRDMO/model/models.py
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
def fetch_formula_data(qids: list) -> dict:
    '''Fetch defining formula and in-defining-formula data via the wbgetentities API.

    Args:
        qids: List of raw QIDs such as ``['Q123', 'Q456']`` (without ``mardi:`` prefix).

    Returns:
        Dict mapping each QID to a result dict with keys:
        ``formulas`` (list[str]), ``symbols`` (list[str]),
        and ``contains_quantity`` (list[Relatant]).
        Returns an empty dict if *qids* is empty.
    '''
    if not qids:
        return {}

    props          = get_properties()
    pid_formula    = props.get('defining formula')
    pid_in_formula = props.get('in defining formula')
    pid_sym_rep    = props.get('symbol represents')
    api_url        = get_url('mardi', 'api')

    entities                    = _wbgetentities_batch(api_url, qids, 'claims')
    intermediate, qty_qids_needed = _parse_formula_claims(
        entities, pid_formula, pid_in_formula, pid_sym_rep
    )
    qty_info = _fetch_qty_labels(api_url, qty_qids_needed)

    return {
        qid: _build_formula_entry(data, qty_info)
        for qid, data in intermediate.items()
    }

Providers

RDMO optionset providers for the Model documentation catalog.

Each provider class implements get_options and is referenced from the model catalog configuration. Providers query MaRDI Portal and Wikidata for entity suggestions and optionally allow to create new entries or restrict suggestions to already-documented entities.

Provides:

  • :class:Formula — formula lookup; refresh on select
  • :class:ResearchField — searches external sources; refresh on select, no creation
  • :class:RelatedResearchFieldWithCreation — searches external sources; no refresh on select, creation
  • :class:RelatedResearchFieldWithoutCreation — searches external sources; no refresh on select, no creation
  • :class:ResearchProblem — searches external sources; refresh on select, no creation
  • :class:RelatedResearchProblemWithCreation — searches external sources; no refresh on select, creation
  • :class:RelatedResearchProblemWithoutCreation — searches external sources; no refresh on select, no creation
  • :class:MathematicalModel — searches external sources; refresh on select, no creation
  • :class:RelatedMathematicalModelWithoutCreation — searches external sources; no refresh on select, no creation
  • :class:QuantityOrQuantityKind — searches external sources; refresh on select, no creation
  • :class:RelatedQuantityWithoutCreation — searches external sources; no refresh on select, no creation
  • :class:RelatedQuantityKindWithoutCreation — searches external sources; no refresh on select, no creation
  • :class:RelatedQuantityOrQuantityKindWithCreation — searches external sources; no refresh on select, creation
  • :class:MathematicalFormulation — searches external sources; refresh on select, no creation
  • :class:RelatedMathematicalFormulationWithCreation — searches external sources; refresh on select, creation
  • :class:RelatedMathematicalFormulationWithoutCreation — searches external sources; not refresh on select, no creation
  • :class:Task — searches external sources; refresh on select, no creation
  • :class:RelatedTaskWithCreation — searches external sources; no refresh on select, creation
  • :class:RelatedTaskWithoutCreation — searches external sources; no refresh on select, no creation
  • :class:RelatedModelEntityWithoutCreation — generic cross-entity lookup without creation

Formula

Bases: Provider

Formula Provider for all sorts of Latex Math. Future Potential: - render Latex Math while entered - definitive safe to automatically extract elements

Source code in MaRDMO/model/providers.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class Formula(Provider):
    '''Formula Provider for all sorts of Latex Math.
       Future Potential:
          - render Latex Math while entered
          - definitive safe to automatically extract elements
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Return the search term verbatim as a single formula option.

        Args:
            project: RDMO project instance (unused).
            search:  LaTeX formula string entered by the user.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List containing one ``{"id": "formula", "text": search}`` dict,
            or an empty list when *search* is empty.
        '''
        return [{'id': 'formula', 'text': search}]

get_options(project, search=None, user=None, site=None)

Return the search term verbatim as a single formula option.

Parameters:

Name Type Description Default
project

RDMO project instance (unused).

required
search

LaTeX formula string entered by the user.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List containing one {"id": "formula", "text": search} dict,

or an empty list when search is empty.

Source code in MaRDMO/model/providers.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def get_options(self, project, search=None, user=None, site=None):
    '''Return the search term verbatim as a single formula option.

    Args:
        project: RDMO project instance (unused).
        search:  LaTeX formula string entered by the user.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List containing one ``{"id": "formula", "text": search}`` dict,
        or an empty list when *search* is empty.
    '''
    return [{'id': 'formula', 'text': search}]

MathematicalFormulation

Bases: Provider

Mathematical Formulation Provider (MaRDI Portal / Wikidata), No User Creation, Refresh Upon Selection

Source code in MaRDMO/model/providers.py
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
class MathematicalFormulation(Provider):
    '''Mathematical Formulation Provider (MaRDI Portal / Wikidata),
       No User Creation, Refresh Upon Selection
    '''

    search = True
    refresh =True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        return query_sources(
            search = search,
            item_class = _ITEMS['mathematical expression']
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    return query_sources(
        search = search,
        item_class = _ITEMS['mathematical expression']
    )

MathematicalModel

Bases: Provider

Mathematical Model Provider (MaRDI Portal / Wikidata), No User Creation, Refresh Upon Selection

Source code in MaRDMO/model/providers.py
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
class MathematicalModel(Provider):
    '''Mathematical Model Provider (MaRDI Portal / Wikidata),
       No User Creation, Refresh Upon Selection
    '''

    search = True
    refresh = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []

        return query_sources(
            search = search,
            item_class = _ITEMS['mathematical model']
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []

    return query_sources(
        search = search,
        item_class = _ITEMS['mathematical model']
    )

QuantityOrQuantityKind

Bases: Provider

Quantity [Kind] Provider (MaRDI Portal / Wikidata), No User Creation, Refresh Upon Selection

Source code in MaRDMO/model/providers.py
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
class QuantityOrQuantityKind(Provider):
    '''Quantity [Kind] Provider (MaRDI Portal / Wikidata),
       No User Creation, Refresh Upon Selection
    '''

    search = True
    refresh =True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        return query_sources(
            search = search,
            item_class = [
                _ITEMS['quantity'],
                _ITEMS['kind of quantity']
            ]
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    return query_sources(
        search = search,
        item_class = [
            _ITEMS['quantity'],
            _ITEMS['kind of quantity']
        ]
    )

RelatedMathematicalFormulationWithCreation

Bases: Provider

Mathematical Formulation Provider (MaRDI Portal / Wikidata), User Creation, Refresh Upon Selection

Source code in MaRDMO/model/providers.py
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
class RelatedMathematicalFormulationWithCreation(Provider):
    '''Mathematical Formulation Provider (MaRDI Portal / Wikidata),
       User Creation, Refresh Upon Selection
    '''

    search = True
    refresh =True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['formulation'],
            creation = True,
            item_class = _ITEMS['mathematical expression']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['formulation'],
        creation = True,
        item_class = _ITEMS['mathematical expression']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedMathematicalFormulationWithoutCreation

Bases: Provider

Mathematical Formulation Provider (MaRDI Portal), No User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
class RelatedMathematicalFormulationWithoutCreation(Provider):
    '''Mathematical Formulation Provider (MaRDI Portal),
       No User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['formulation'],
            sources = ['mardi'],
            item_class = _ITEMS['mathematical expression']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['formulation'],
        sources = ['mardi'],
        item_class = _ITEMS['mathematical expression']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedMathematicalModelWithoutCreation

Bases: Provider

Mathematical Model Provider (MaRDI Portal / Wikidata), User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
class RelatedMathematicalModelWithoutCreation(Provider):
    '''Mathematical Model Provider (MaRDI Portal / Wikidata),
       User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['model'],
            sources = ['mardi'],
            item_class = _ITEMS['mathematical model']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['model'],
        sources = ['mardi'],
        item_class = _ITEMS['mathematical model']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedModelEntityWithoutCreation

Bases: Provider

Research Field, Research Problem, Mathematical Model, Mathematical Formulation, Quantity [Kind], Task Provider (MaRDI Portal / Wikidata), No User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
class RelatedModelEntityWithoutCreation(Provider):
    '''Research Field, Research Problem, Mathematical Model,
       Mathematical Formulation, Quantity [Kind], Task Provider 
       (MaRDI Portal / Wikidata), No User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query the MathModDB ontology and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['field', 'problem', 'model', 'quantity', 'formulation', 'task'],
            sources = ['mardi'],
            item_class = [
                _ITEMS['academic discipline'],
                _ITEMS['research problem'],
                _ITEMS['mathematical model'],
                _ITEMS['quantity'],
                _ITEMS['kind of quantity'],
                _ITEMS['mathematical expression'],
                _ITEMS['computational task']
            ]
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query the MathModDB ontology and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
def get_options(self, project, search=None, user=None, site=None):
    '''Query the MathModDB ontology and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['field', 'problem', 'model', 'quantity', 'formulation', 'task'],
        sources = ['mardi'],
        item_class = [
            _ITEMS['academic discipline'],
            _ITEMS['research problem'],
            _ITEMS['mathematical model'],
            _ITEMS['quantity'],
            _ITEMS['kind of quantity'],
            _ITEMS['mathematical expression'],
            _ITEMS['computational task']
        ]
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedQuantityKindWithoutCreation

Bases: Provider

Quantity Kind Provider (MaRDI Portal), No User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
class RelatedQuantityKindWithoutCreation(Provider):
    '''Quantity Kind Provider (MaRDI Portal),
       No User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['quantity'],
            sources = ['mardi'],
            item_class = _ITEMS['kind of quantity']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['quantity'],
        sources = ['mardi'],
        item_class = _ITEMS['kind of quantity']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedQuantityOrQuantityKindWithCreation

Bases: Provider

Quantity [Kind] Provider (MaRDI Portal / Wikidata), User Creation, Refresh Upon Selection

Source code in MaRDMO/model/providers.py
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
class RelatedQuantityOrQuantityKindWithCreation(Provider):
    '''Quantity [Kind] Provider (MaRDI Portal / Wikidata),
       User Creation, Refresh Upon Selection
    '''

    search = True
    refresh =True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['quantity'],
            creation = True,
            item_class = [
                _ITEMS['quantity'],
                _ITEMS['kind of quantity']
            ]
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['quantity'],
        creation = True,
        item_class = [
            _ITEMS['quantity'],
            _ITEMS['kind of quantity']
        ]
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedQuantityWithoutCreation

Bases: Provider

Quantity Provider (MaRDI Portal), No User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
class RelatedQuantityWithoutCreation(Provider):
    '''Quantity Provider (MaRDI Portal),
       No User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['quantity'],
            sources = ['mardi'],
            item_class = _ITEMS['quantity']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['quantity'],
        sources = ['mardi'],
        item_class = _ITEMS['quantity']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedResearchFieldWithCreation

Bases: Provider

Research Field Provider (MaRDI Portal / Wikidata), User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
class RelatedResearchFieldWithCreation(Provider):
    '''Research Field Provider (MaRDI Portal / Wikidata),
       User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['field'],
            creation = True,
            item_class = _ITEMS['academic discipline']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['field'],
        creation = True,
        item_class = _ITEMS['academic discipline']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedResearchFieldWithoutCreation

Bases: Provider

Research Field Provider (MaRDI Portal), No User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
class RelatedResearchFieldWithoutCreation(Provider):
    '''Research Field Provider (MaRDI Portal),
       No User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['field'],
            sources = ['mardi'],
            item_class = _ITEMS['academic discipline']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['field'],
        sources = ['mardi'],
        item_class = _ITEMS['academic discipline']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedResearchProblemWithCreation

Bases: Provider

Research Problem Provider (MaRDI Portal / Wikidata), User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
class RelatedResearchProblemWithCreation(Provider):
    '''Research Problem Provider (MaRDI Portal / Wikidata),
       User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []

        # Define the query_setup
        setup = define_setup(
            query_attributes = ['problem'],
            creation = True,
            item_class = _ITEMS['research problem']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []

    # Define the query_setup
    setup = define_setup(
        query_attributes = ['problem'],
        creation = True,
        item_class = _ITEMS['research problem']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedResearchProblemWithoutCreation

Bases: Provider

Research Problem Provider (MaRDI Portal), No User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
class RelatedResearchProblemWithoutCreation(Provider):
    '''Research Problem Provider (MaRDI Portal),
       No User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['problem'],
            sources = ['mardi'],
            item_class = _ITEMS['research problem']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['problem'],
        sources = ['mardi'],
        item_class = _ITEMS['research problem']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedTaskWithCreation

Bases: Provider

Task Provider (MaRDI Portal / Wikidata), User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
class RelatedTaskWithCreation(Provider):
    '''Task Provider (MaRDI Portal / Wikidata),
       User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query the MathModDB ontology and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['task'],
            creation = True,
            item_class = _ITEMS['computational task']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query the MathModDB ontology and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
def get_options(self, project, search=None, user=None, site=None):
    '''Query the MathModDB ontology and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['task'],
        creation = True,
        item_class = _ITEMS['computational task']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

RelatedTaskWithoutCreation

Bases: Provider

Task Provider (MaRDI Portal), No User Creation, No Refresh Upon Selection

Source code in MaRDMO/model/providers.py
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
class RelatedTaskWithoutCreation(Provider):
    '''Task Provider (MaRDI Portal),
       No User Creation, No Refresh Upon Selection
    '''

    search = True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query the MathModDB ontology and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        # Define the query_setup
        setup = define_setup(
            query_attributes = ['task'],
            sources = ['mardi'],
            item_class = _ITEMS['computational task']
        )

        return query_sources_with_user_additions(
            search = search,
            project = project,
            setup = setup
        )

get_options(project, search=None, user=None, site=None)

Query the MathModDB ontology and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
def get_options(self, project, search=None, user=None, site=None):
    '''Query the MathModDB ontology and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    # Define the query_setup
    setup = define_setup(
        query_attributes = ['task'],
        sources = ['mardi'],
        item_class = _ITEMS['computational task']
    )

    return query_sources_with_user_additions(
        search = search,
        project = project,
        setup = setup
    )

ResearchField

Bases: Provider

Research Field Provider (MaRDI Portal / Wikidata), No User Creation, Refresh Upon Selection

Source code in MaRDMO/model/providers.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
class ResearchField(Provider):
    '''Research Field Provider (MaRDI Portal / Wikidata),
       No User Creation, Refresh Upon Selection
    '''

    search = True
    refresh =True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []

        return query_sources(
            search = search,
            item_class = [
                _ITEMS['academic discipline']
            ]
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []

    return query_sources(
        search = search,
        item_class = [
            _ITEMS['academic discipline']
        ]
    )

ResearchProblem

Bases: Provider

Research Problem Provider (MaRDI Portal / Wikidata), No User Creation, Refresh Upon Selection

Source code in MaRDMO/model/providers.py
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
class ResearchProblem(Provider):
    '''Research Problem Provider (MaRDI Portal / Wikidata),
       No User Creation, Refresh Upon Selection
    '''

    search = True
    refresh =True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query external knowledge-graph source(s) and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []

        return query_sources(
            search = search,
            item_class = _ITEMS['research problem']
        )

get_options(project, search=None, user=None, site=None)

Query external knowledge-graph source(s) and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
def get_options(self, project, search=None, user=None, site=None):
    '''Query external knowledge-graph source(s) and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []

    return query_sources(
        search = search,
        item_class = _ITEMS['research problem']
    )

Task

Bases: Provider

Task Provider (MaRDI Portal / Wikidata), No User Creation, Refresh Upon Selection

Source code in MaRDMO/model/providers.py
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
class Task(Provider):
    '''Task Provider (MaRDI Portal / Wikidata),
       No User Creation, Refresh Upon Selection
    '''

    search = True
    refresh =True

    def get_options(self, project, search=None, user=None, site=None):
        '''Query the MathModDB ontology and return matching options.

        Args:
            project: RDMO project instance (used for user-entry lookups when applicable).
            search:  Search string entered by the user; returns empty list when
                     fewer than 3 characters.
            user:    Requesting user (unused).
            site:    Current site (unused).

        Returns:
            List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
        '''
        if not search or len(search) < 3:
            return []


        return query_sources(
            search = search,
            item_class = _ITEMS['computational task']
        )

get_options(project, search=None, user=None, site=None)

Query the MathModDB ontology and return matching options.

Parameters:

Name Type Description Default
project

RDMO project instance (used for user-entry lookups when applicable).

required
search

Search string entered by the user; returns empty list when fewer than 3 characters.

None
user

Requesting user (unused).

None
site

Current site (unused).

None

Returns:

Type Description

List of {"id": …, "text": …} option dicts sorted by relevance.

Source code in MaRDMO/model/providers.py
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
def get_options(self, project, search=None, user=None, site=None):
    '''Query the MathModDB ontology and return matching options.

    Args:
        project: RDMO project instance (used for user-entry lookups when applicable).
        search:  Search string entered by the user; returns empty list when
                 fewer than 3 characters.
        user:    Requesting user (unused).
        site:    Current site (unused).

    Returns:
        List of ``{"id": …, "text": …}`` option dicts sorted by relevance.
    '''
    if not search or len(search) < 3:
        return []


    return query_sources(
        search = search,
        item_class = _ITEMS['computational task']
    )

Workers

Background worker for the Model documentation catalog.

Implements the task that collects mathematical model metadata from User, MarDI Portal, and Wikidata, renders a preview document, and exports the result to the MaRDI Portal.

Provides:

  • :class:PrepareModel — orchestrates data collection, preview rendering, and portal export for a single model documentation project

PrepareModel

Bases: PublicationExport

Prepare Mathematical Model answers for preview rendering and MaRDI Portal export.

Inherits publication export helpers from :class:~MaRDMO.publication.worker.PublicationExport and extends them with model-specific relation mapping, property conflict detection, and Wikibase payload generation.

Source code in MaRDMO/model/worker.py
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
class PrepareModel(PublicationExport):
    '''Prepare Mathematical Model answers for preview rendering and MaRDI Portal export.

    Inherits publication export helpers from
    :class:`~MaRDMO.publication.worker.PublicationExport` and extends them
    with model-specific relation mapping, property conflict detection, and
    Wikibase payload generation.
    '''
    def __init__(self):
        '''Initialise with Wikibase vocabulary and the MathModDB ontology registry.'''
        super().__init__()
        self.mathmoddb = get_mathmoddb()

    def preview(self, answers):
        '''Resolve entity cross-references and property checks for the preview page.

        Applies general label/relation mappings, entity-relation links, and
        data-property conflict detection so that the preview template receives
        a fully-resolved answers dict.

        Args:
            answers: Top-level answers dict (mutated in place).

        Returns:
            The mutated *answers* dict.
        '''

        # Prepare General Mappings
        for mapping in preview_map_general:
            map_entity(
                data = answers,
                idx = {
                    'from': mapping[0],
                    'to': mapping[1]
                },
                entity = {
                    'old_name': mapping[2],
                    'new_name': mapping[3],
                    'encryption': mapping[4]
                }
            )

        # Prepare Relations for Preview
        for relation in preview_relations:
            entity_relations(
                data = answers,
                idx = {
                    'from': relation['from_idx'],
                    'to': relation['to_idx']
                },
                entity = {
                    'relation': relation['relation'],
                    'old_name': relation['old_name'],
                    'new_name': relation['new_name'],
                    'encryption': relation['encryption']
                },
                order = {
                    'formulation': relation['formulation'],
                    'task': relation['task']
                },
                assumption = relation['assumption'],
                mapping = self.mathmoddb
            )

        # Quantity Type as Label
        for quantity in answers.get("quantity", {}).values():
            if quantity.get("QorQK"):
                quantity['QorQK'] = self.mathmoddb.get(url=quantity["QorQK"])['label']

        # Prepare Quantity Mapping
        for mapping in preview_map_quantity:
            map_entity_quantity(
                data = answers,
                entity_type = mapping
            )

        # Check Data Properties for Preview
        for mathmoddb_class in answers.values():
            for class_item in mathmoddb_class.values():
                properties = class_item.get('Properties')
                if not properties:
                    continue

                present = set(properties.values())
                wrong = set()

                for pair in data_properties_check:
                    opt_a, opt_b = self.mathmoddb.get(key=pair[0])["url"], self.mathmoddb.get(key=pair[1])["url"]
                    if {opt_a, opt_b}.issubset(present):
                        wrong.update([pair[0], pair[1]])
                        present.discard(opt_a)
                        present.discard(opt_b)

                correct = {key for key in data_properties_label if self.mathmoddb.get(key=key)["url"] in present}

                class_item['Properties_Check'] = [
                    {'label': data_properties_label[k], 'error': k in wrong}
                    for k in correct | wrong
                ]

        return answers

    def export(self, data, url):
        '''Assemble and return the complete Wikibase payload for a Model documentation export.

        Creates a :class:`~MaRDMO.payload.GeneratePayload` instance, processes
        all unique items, then delegates each entity section (fields, problems,
        models, formulations, quantities, tasks, publications) to dedicated
        helper methods.

        Args:
            data: Top-level answers dict produced by ``get_post_data``.
            url:  Target Wikibase API URL for the upload.

        Returns:
            Tuple ``(payload_dict, dependency_order)`` ready for
            :meth:`~MaRDMO.oauth2.OauthProviderMixin.post`.
        '''

        items, dependency = unique_items(data)

        payload = GeneratePayload(
            dependency = dependency,
            user_items = items,
            url = url,
            wikibase = {
                'data_properties': get_data_properties,
                'items': get_items(),
                'properties': get_properties(),
                'relations': get_relations()
            }
        )

        # Add / Retrieve Components of Model Item
        payload.process_items()

        # Delegate to helper functions
        self._export_fields(
            payload = payload,
            fields = data.get("field", {}),
        )
        self._export_problems(
            payload = payload,
            problems = data.get("problem", {})
        )
        self._export_models(
            payload = payload,
            models = data.get("model", {})
        )
        self._export_tasks(
            payload = payload,
            tasks = data.get("task", {})
        )
        self._export_formulations(
            payload = payload,
            formulations = data.get("formulation", {})
        )
        self._export_quantities(
            payload = payload,
            quantities = data.get("quantity", {})
        )
        self._export_authors(
            payload = payload,
            publications = data.get("publication", {})
        )
        self._export_journals(
            payload = payload,
            publications = data.get("publication", {})
        )
        self._export_publications(
            payload = payload,
            publications = data.get("publication", {}),
            relations = [('P2E', 'EntityRelatant')]
        )

        # Construct Item Payloads
        payload.add_item_payload()

        # If Relations are added, check if they exist
        if any(
            key.startswith("RELATION")
            for key in payload.get_dictionary()
        ):
            query = payload.build_relation_check_query()

            check = None
            for attempt in range(2):  # try twice
                try:
                    check = query_sparql(
                        query = query,
                        sparql_endpoint = get_url('mardi', 'sparql')
                    )
                    break
                except Exception as e:
                    logging.warning("SPARQL query attempt %s failed: %s", attempt + 1, e)
                    if attempt == 0:
                        time.sleep(1)  # short wait before retry
            if not check:
                # both attempts failed → pretend no results
                check = [{}]

            # SPARQL returns math values as MathML; check math statements via API
            math_check = payload.check_math_relations_via_api(get_url('mardi', 'api'))
            if math_check:
                relation_keys = [
                    k for k in payload.get_dictionary() if k.startswith('RELATION')
                ]
                for idx, key in enumerate(relation_keys):
                    if key in math_check:
                        check[0][f'RELATION{idx}'] = {
                            'value': math_check[key],
                            'type':  'literal',
                        }

            payload.add_check_results(
                check = check
            )
        return payload.get_dictionary(), payload.dependency

    # ---------------------------
    # Shared helper
    # ---------------------------
    def _add_common_metadata(self, payload, qclass, profile_type):
        '''Add instance-of, community, and MaRDI-profile-type statements to the current item.

        Args:
            payload:      :class:`~MaRDMO.payload.GeneratePayload` instance.
            qclass:       Wikibase QID for the ``instance of`` target class.
            profile_type: Label key for the MaRDI profile type item.
        '''
        payload.add_answer(
            verb = self.properties["instance of"],
            object_and_type = [qclass, "wikibase-item"],
        )

        payload.add_answer(
            verb = self.properties["community"],
            object_and_type = [self.items["MathModDB"], "wikibase-item"],
        )

        payload.add_answer(
            verb = self.properties["MaRDI profile type"],
            object_and_type = [self.items[profile_type], "wikibase-item"],
        )

        payload.add_answers(
            mardmo_property = "descriptionLong",
            wikibase_property = "description",
        )

    # ---------------------------
    # Entity export helpers
    # ---------------------------
    def _export_fields(self, payload, fields: dict):
        for entry in fields.values():
            if not entry.get("ID"):
                continue

            payload.get_item_key(
                value = entry
            )

            self._add_common_metadata(
                payload = payload,
                qclass = self.items["academic discipline"],
                profile_type = "MaRDI research field profile",
            )

            payload.add_aliases(
                aliases_dict = entry.get('Alias')
            )

            payload.add_multiple_relation(
                statement = {
                    'relation': "IntraClassRelation",
                    'relatant': "IntraClassElement"
                }
            )

    def _export_problems(self, payload, problems: dict):
        for entry in problems.values():
            if not entry.get("ID"):
                continue

            payload.get_item_key(
                value = entry
            )

            self._add_common_metadata(
                payload = payload,
                qclass = self.items["research problem"],
                profile_type = "MaRDI research problem profile",
            )

            payload.add_aliases(
                aliases_dict = entry.get('Alias')
            )

            payload.add_single_relation(
                statement = {
                    'relation': self.properties["contains"],
                    'relatant': "RFRelatant"
                },
                reverse = True
            )

            payload.add_multiple_relation(
                statement = {
                    'relation': "IntraClassRelation",
                    'relatant': "IntraClassElement"
                }
            )

    def _export_models(self, payload, models: dict):
        for entry in models.values():
            if not entry.get("ID"):
                continue

            payload.get_item_key(
                value = entry
            )

            self._add_common_metadata(
                payload = payload,
                qclass = self.items["mathematical model"],
                profile_type = "MaRDI model profile",
            )

            payload.add_aliases(
                aliases_dict = entry.get('Alias')
            )

            payload.add_data_properties(
                item_class = "model"
            )

            payload.add_multiple_relation(
                statement = {
                    'relation': "MM2MF",
                    'relatant': "MFRelatant"
                },
                optional_qualifier = ['series ordinal']
            )

            payload.add_single_relation(
                statement = {
                    'relation': self.properties["modelled by"],
                    'relatant': "RPRelatant"
                },
                reverse = True
            )

            payload.add_single_relation(
                statement = {
                    'relation': self.properties["used by"],
                    'relatant': "TRelatant"
                }
            )

            payload.add_multiple_relation(
                statement = {
                    'relation': "IntraClassRelation",
                    'relatant': "IntraClassElement"
                },
                optional_qualifier = ['assumes']
            )

    def _export_tasks(self, payload, tasks: dict):
        for entry in tasks.values():
            if not entry.get("ID"):
                continue

            payload.get_item_key(
                value = entry
            )

            self._add_common_metadata(
                payload = payload,
                qclass = self.items["computational task"],
                profile_type = "MaRDI task profile",
            )

            payload.add_aliases(
                aliases_dict = entry.get('Alias')
            )

            payload.add_data_properties(
                item_class = "task"
            )

            payload.add_multiple_relation(
                statement = {
                    'relation': "T2MF",
                    'relatant': "MFRelatant"
                }
            )

            payload.add_multiple_relation(
                statement = {
                    'relation': "T2Q",
                    'relatant': "QRelatant"
                }
            )

            payload.add_multiple_relation(
                statement = {
                    'relation': "IntraClassRelation",
                    'relatant': "IntraClassElement"
                },
                optional_qualifier = ['assumes', 'series ordinal']
            )

    def _export_formulations(self, payload, formulations: dict):
        for entry in formulations.values():
            if not entry.get("ID"):
                continue

            payload.get_item_key(
                value = entry
            )

            self._add_common_metadata(
                payload = payload,
                qclass = self.items["mathematical expression"],
                profile_type = "MaRDI formula profile",
            )

            payload.add_aliases(
                aliases_dict = entry.get('Alias')
            )

            payload.add_data_properties(
                item_class = "equation"
            )

            if entry.get('reference'):
                payload.add_answer(
                    verb = self.properties["comment"],
                    object_and_type = [entry.get('reference'), "string"],
                )

            payload.add_answers(
                mardmo_property = "Formula",
                wikibase_property = "defining formula",
                datatype = "math",
            )

            payload.add_in_defining_formula()

            payload.add_multiple_relation(
                statement = {
                    'relation': "MF2MF",
                    'relatant': "MFRelatant"
                }
            )

            payload.add_multiple_relation(
                statement = {
                    'relation': "IntraClassRelation",
                    'relatant': "IntraClassElement"
                },
                optional_qualifier = ['assumes']
            )

    def _export_quantities(self, payload, quantities: dict):
        for entry in quantities.values():
            if not entry.get("ID"):
                continue

            payload.get_item_key(
                value = entry
            )

            if entry.get("QorQK") == self.mathmoddb.get(label='Quantity')['url']:
                self._add_common_metadata(
                    payload = payload,
                    qclass = self.items["quantity"],
                    profile_type = "MaRDI quantity profile",
                )
                qtype = "quantity"

            elif entry.get("QorQK") == self.mathmoddb.get(label='Quantity Kind')['url']:
                self._add_common_metadata(
                    payload = payload,
                    qclass = self.items["kind of quantity"],
                    profile_type = "MaRDI quantity profile",
                )
                qtype = "quantity kind"

            else:
                continue

            payload.add_aliases(
                aliases_dict = entry.get('Alias')
            )

            payload.add_data_properties(
                item_class = qtype
            )

            if (
                entry.get("reference")
                and qtype == "quantity kind"
            ):
                payload.add_answer(
                    verb = self.properties["QUDT quantity kind ID"],
                    object_and_type = [entry["reference"][0][1], "external-id"],
                )

            if (
                entry.get("reference")
                and qtype == "quantity"
            ):
                payload.add_answer(
                    verb = self.properties["QUDT constant ID"],
                    object_and_type = [entry["reference"][1][1], "external-id"],
                )

            payload.add_answers(
                mardmo_property = "Formula",
                wikibase_property = "defining formula",
                datatype = "math",
            )

            payload.add_in_defining_formula()

            if qtype == "quantity":
                payload.add_multiple_relation(
                    statement = {
                        'relation': "Q2Q",
                        'relatant': "QRelatant-Q"
                    }
                )

                payload.add_multiple_relation(
                    statement = {
                        'relation': "Q2QK",
                        'relatant': "QKRelatant-Q"
                    }
                )

            else:
                payload.add_multiple_relation(
                    statement = {
                        'relation': "QK2QK",
                        'relatant': "QKRelatant-QK"
                    }
                )

                payload.add_multiple_relation(
                    statement = {
                        'relation': "QK2Q",
                        'relatant': "QRelatant-QK"
                    }
                )

__init__()

Initialise with Wikibase vocabulary and the MathModDB ontology registry.

Source code in MaRDMO/model/worker.py
41
42
43
44
def __init__(self):
    '''Initialise with Wikibase vocabulary and the MathModDB ontology registry.'''
    super().__init__()
    self.mathmoddb = get_mathmoddb()

export(data, url)

Assemble and return the complete Wikibase payload for a Model documentation export.

Creates a :class:~MaRDMO.payload.GeneratePayload instance, processes all unique items, then delegates each entity section (fields, problems, models, formulations, quantities, tasks, publications) to dedicated helper methods.

Parameters:

Name Type Description Default
data

Top-level answers dict produced by get_post_data.

required
url

Target Wikibase API URL for the upload.

required

Returns:

Type Description

Tuple (payload_dict, dependency_order) ready for

meth:~MaRDMO.oauth2.OauthProviderMixin.post.

Source code in MaRDMO/model/worker.py
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
def export(self, data, url):
    '''Assemble and return the complete Wikibase payload for a Model documentation export.

    Creates a :class:`~MaRDMO.payload.GeneratePayload` instance, processes
    all unique items, then delegates each entity section (fields, problems,
    models, formulations, quantities, tasks, publications) to dedicated
    helper methods.

    Args:
        data: Top-level answers dict produced by ``get_post_data``.
        url:  Target Wikibase API URL for the upload.

    Returns:
        Tuple ``(payload_dict, dependency_order)`` ready for
        :meth:`~MaRDMO.oauth2.OauthProviderMixin.post`.
    '''

    items, dependency = unique_items(data)

    payload = GeneratePayload(
        dependency = dependency,
        user_items = items,
        url = url,
        wikibase = {
            'data_properties': get_data_properties,
            'items': get_items(),
            'properties': get_properties(),
            'relations': get_relations()
        }
    )

    # Add / Retrieve Components of Model Item
    payload.process_items()

    # Delegate to helper functions
    self._export_fields(
        payload = payload,
        fields = data.get("field", {}),
    )
    self._export_problems(
        payload = payload,
        problems = data.get("problem", {})
    )
    self._export_models(
        payload = payload,
        models = data.get("model", {})
    )
    self._export_tasks(
        payload = payload,
        tasks = data.get("task", {})
    )
    self._export_formulations(
        payload = payload,
        formulations = data.get("formulation", {})
    )
    self._export_quantities(
        payload = payload,
        quantities = data.get("quantity", {})
    )
    self._export_authors(
        payload = payload,
        publications = data.get("publication", {})
    )
    self._export_journals(
        payload = payload,
        publications = data.get("publication", {})
    )
    self._export_publications(
        payload = payload,
        publications = data.get("publication", {}),
        relations = [('P2E', 'EntityRelatant')]
    )

    # Construct Item Payloads
    payload.add_item_payload()

    # If Relations are added, check if they exist
    if any(
        key.startswith("RELATION")
        for key in payload.get_dictionary()
    ):
        query = payload.build_relation_check_query()

        check = None
        for attempt in range(2):  # try twice
            try:
                check = query_sparql(
                    query = query,
                    sparql_endpoint = get_url('mardi', 'sparql')
                )
                break
            except Exception as e:
                logging.warning("SPARQL query attempt %s failed: %s", attempt + 1, e)
                if attempt == 0:
                    time.sleep(1)  # short wait before retry
        if not check:
            # both attempts failed → pretend no results
            check = [{}]

        # SPARQL returns math values as MathML; check math statements via API
        math_check = payload.check_math_relations_via_api(get_url('mardi', 'api'))
        if math_check:
            relation_keys = [
                k for k in payload.get_dictionary() if k.startswith('RELATION')
            ]
            for idx, key in enumerate(relation_keys):
                if key in math_check:
                    check[0][f'RELATION{idx}'] = {
                        'value': math_check[key],
                        'type':  'literal',
                    }

        payload.add_check_results(
            check = check
        )
    return payload.get_dictionary(), payload.dependency

preview(answers)

Resolve entity cross-references and property checks for the preview page.

Applies general label/relation mappings, entity-relation links, and data-property conflict detection so that the preview template receives a fully-resolved answers dict.

Parameters:

Name Type Description Default
answers

Top-level answers dict (mutated in place).

required

Returns:

Type Description

The mutated answers dict.

Source code in MaRDMO/model/worker.py
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def preview(self, answers):
    '''Resolve entity cross-references and property checks for the preview page.

    Applies general label/relation mappings, entity-relation links, and
    data-property conflict detection so that the preview template receives
    a fully-resolved answers dict.

    Args:
        answers: Top-level answers dict (mutated in place).

    Returns:
        The mutated *answers* dict.
    '''

    # Prepare General Mappings
    for mapping in preview_map_general:
        map_entity(
            data = answers,
            idx = {
                'from': mapping[0],
                'to': mapping[1]
            },
            entity = {
                'old_name': mapping[2],
                'new_name': mapping[3],
                'encryption': mapping[4]
            }
        )

    # Prepare Relations for Preview
    for relation in preview_relations:
        entity_relations(
            data = answers,
            idx = {
                'from': relation['from_idx'],
                'to': relation['to_idx']
            },
            entity = {
                'relation': relation['relation'],
                'old_name': relation['old_name'],
                'new_name': relation['new_name'],
                'encryption': relation['encryption']
            },
            order = {
                'formulation': relation['formulation'],
                'task': relation['task']
            },
            assumption = relation['assumption'],
            mapping = self.mathmoddb
        )

    # Quantity Type as Label
    for quantity in answers.get("quantity", {}).values():
        if quantity.get("QorQK"):
            quantity['QorQK'] = self.mathmoddb.get(url=quantity["QorQK"])['label']

    # Prepare Quantity Mapping
    for mapping in preview_map_quantity:
        map_entity_quantity(
            data = answers,
            entity_type = mapping
        )

    # Check Data Properties for Preview
    for mathmoddb_class in answers.values():
        for class_item in mathmoddb_class.values():
            properties = class_item.get('Properties')
            if not properties:
                continue

            present = set(properties.values())
            wrong = set()

            for pair in data_properties_check:
                opt_a, opt_b = self.mathmoddb.get(key=pair[0])["url"], self.mathmoddb.get(key=pair[1])["url"]
                if {opt_a, opt_b}.issubset(present):
                    wrong.update([pair[0], pair[1]])
                    present.discard(opt_a)
                    present.discard(opt_b)

            correct = {key for key in data_properties_label if self.mathmoddb.get(key=key)["url"] in present}

            class_item['Properties_Check'] = [
                {'label': data_properties_label[k], 'error': k in wrong}
                for k in correct | wrong
            ]

    return answers

Constants

Compile-time constants and configuration builders for the Model catalog.

Centralises the property URIs, relation definitions, and question/item mappings that the model documentation sub-package needs at runtime. Values are loaded once from the RDMO database via the getters helpers and then referenced by handlers, providers, and workers.

Provides:

  • get_relations() — returns the full relation-definition dict for mathematical models
  • get_uri_prefix_map() — returns the {prefix: URI} map used to expand compact IDs
  • Module-level constants built from the above (RELATIONS, URI_PREFIX_MAP, etc.)

get_relations()

Build the relation mapping for the Model Documentation.

Maps each MathModDB relation URL to the corresponding Wikibase property (and optional qualifier item or direction string) used when writing statements to the MaRDI Portal.

Returns:

Type Description

Dict mapping MathModDB relation URL strings to [property(, qualifier)]

lists; qualifier is either a Wikibase item ID or 'forward'/'backward'.

Source code in MaRDMO/model/constants.py
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
def get_relations():
    '''Build the relation mapping for the Model Documentation.

    Maps each MathModDB relation URL to the corresponding Wikibase property
    (and optional qualifier item or direction string) used when writing
    statements to the MaRDI Portal.

    Returns:
        Dict mapping MathModDB relation URL strings to ``[property(, qualifier)]``
        lists; qualifier is either a Wikibase item ID or ``'forward'``/``'backward'``.
    '''
    mathmoddb = get_mathmoddb()
    items = get_items()
    properties = get_properties()
    relations = {
        # Map MathModDB Relation on Wikibase Property + Qualifier Item
        mathmoddb.get(key='assumes')['url']: [
            properties['assumes']
        ],
        mathmoddb.get(key='contains_boundary_condition')['url']: [
            properties['contains'],
            items['boundary condition']
        ],
        mathmoddb.get(key='contains_constraint_condition')['url']: [
            properties['contains'],
            items['constraint']
        ],
        mathmoddb.get(key='contains_coupling_condition')['url']: [
            properties['contains'],
            items['coupling condition']
        ],
        mathmoddb.get(key='contains_initial_condition')['url']: [
            properties['contains'],
            items['initial condition']
        ],
        mathmoddb.get(key='contains_final_condition')['url']: [
            properties['contains'],
            items['final condition']
        ],
        mathmoddb.get(key='contains_input')['url']: [
            properties['contains'],
            items['input']
        ],
        mathmoddb.get(key='contains_constant')['url']: [
            properties['contains'],
            items['constant']
        ],
        mathmoddb.get(key='contains_objective')['url']: [
            properties['contains'],
            items['objective function']
        ],
        mathmoddb.get(key='contains_output')['url']: [
            properties['contains'],
            items['output']
        ],
        mathmoddb.get(key='contains_parameter')['url']: [
            properties['contains'],
            items['parameter']
        ],
        mathmoddb.get(key='contains_analytical_solution')['url']: [
            properties['contains'],
            items['analytical solution']
        ],
        mathmoddb.get(key='contains_physical_law')['url']: [
            properties['contains'],
            items['physical law']
        ],
        mathmoddb.get(key='contains_computational_domain')['url']: [
            properties['contains'],
            items['computational domain']
        ],
        mathmoddb.get(key='contains_constitutive_equation')['url']: [
            properties['contains'],
            items['constitutive equation']
        ],
        mathmoddb.get(key='contains_weak_formulation')['url']: [
            properties['contains'],
            items['weak formulation']
        ],
        mathmoddb.get(key='contains_strong_formulation')['url']: [
            properties['contains'],
            items['strong formulation']
        ],
        mathmoddb.get(key='documents')['url']: [
            properties['described by source'],
            items['documentation']
        ],
        mathmoddb.get(key='invents')['url']: [
            properties['described by source'],
            items['invention']
        ],
        mathmoddb.get(key='studies')['url']: [
            properties['described by source'],
            items['study']
        ],
        mathmoddb.get(key='surveys')['url']: [
            properties['described by source'],
            items['review']
        ],
        mathmoddb.get(key='uses')['url']: [
            properties['described by source'],
            items['use']
        ],
        # Map MathModDB Relation on Wikibase Property + Direction
        mathmoddb.get(key='specialized_by')['url']: [
            properties['specialized by'],
            'forward'
        ],
        mathmoddb.get(key='specializes')['url']: [
            properties['specialized by'],
            'backward'
        ],
        mathmoddb.get(key='approximated_by')['url']: [
            properties['approximated by'],
            'forward'
        ],
        mathmoddb.get(key='approximates')['url']: [
            properties['approximated by'],
            'backward'
        ],
        mathmoddb.get(key='discretized_by')['url']: [
            properties['discretized by'],
            'forward'
        ],
        mathmoddb.get(key='discretizes')['url']: [
            properties['discretized by'],
            'backward'
        ],
        mathmoddb.get(key='linearized_by')['url']: [
            properties['linearized by'],
            'forward'
        ],
        mathmoddb.get(key='linearizes')['url']: [
            properties['linearized by'],
            'backward'
        ],
        mathmoddb.get(key='nondimensionalized_by')['url']: [
            properties['nondimensionalized by'],
            'forward'
        ],
        mathmoddb.get(key='nondimensionalizes')['url']: [
            properties['nondimensionalized by'],
            'backward'
        ],
        mathmoddb.get(key='contains')['url']: [
            properties['contains'],
            'forward'
        ],
        mathmoddb.get(key='contained_in')['url']: [
            properties['contains'],
            'backward'
        ],
        mathmoddb.get(key='similar_to')['url']: [
            properties['similar to'],
            'forward'
        ],
        mathmoddb.get(key='has_weak_formulation')['url']: [
            properties['has weak formulation'],
            'forward'
        ],
        mathmoddb.get(key='is_weak_formulation_of')['url']: [
            properties['has weak formulation'],
            'backward'
        ]
    }
    return relations

get_uri_prefix_map()

Build the attribute-URI → section config mapping for the Model Documentation.

Maps each relation attribute URI (used as a trigger in the handler map) to the corresponding questionnaire section metadata needed to add or hydrate the related entity.

Returns:

Type Description

Dict mapping full RDMO attribute URI strings to dicts with keys

question_set (section root URI), question_id (ID field URI),

and prefix (label prefix string, e.g. "AD").

Source code in MaRDMO/model/constants.py
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
def get_uri_prefix_map():
    '''Build the attribute-URI → section config mapping for the Model Documentation.

    Maps each relation attribute URI (used as a trigger in the handler map) to
    the corresponding questionnaire section metadata needed to add or hydrate
    the related entity.

    Returns:
        Dict mapping full RDMO attribute URI strings to dicts with keys
        ``question_set`` (section root URI), ``question_id`` (ID field URI),
        and ``prefix`` (label prefix string, e.g. ``"AD"``).
    '''
    questions = get_questions('model')
    uri_prefix_map = {
        f'{BASE_URI}{questions["Task"]["QRelatant"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Quantity"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Quantity"]["ID"]["uri"]}',
            "prefix": "QQK"
        },
        f'{BASE_URI}{questions["Task"]["MFRelatant"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Mathematical Formulation"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Mathematical Formulation"]["ID"]["uri"]}',
            "prefix": "ME"
        },
        f'{BASE_URI}{questions["Mathematical Formulation"]["Element Quantity"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Quantity"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Quantity"]["ID"]["uri"]}',
            "prefix": "QQK"
        },
        f'{BASE_URI}{questions["Quantity"]["Element Quantity"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Quantity"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Quantity"]["ID"]["uri"]}',
            "prefix": "QQK"
        },
        f'{BASE_URI}{questions["Mathematical Model"]["MFRelatant"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Mathematical Formulation"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Mathematical Formulation"]["ID"]["uri"]}',
            "prefix": "ME"
        },
        f'{BASE_URI}{questions["Mathematical Model"]["Assumption"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Mathematical Formulation"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Mathematical Formulation"]["ID"]["uri"]}',
            "prefix": "ME"
        },
        f'{BASE_URI}{questions["Task"]["Assumption"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Mathematical Formulation"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Mathematical Formulation"]["ID"]["uri"]}',
            "prefix": "ME"
        },
        f'{BASE_URI}{questions["Mathematical Formulation"]["Assumption"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Mathematical Formulation"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Mathematical Formulation"]["ID"]["uri"]}',
            "prefix": "ME"
        },
        f'{BASE_URI}{questions["Mathematical Formulation"]["MFRelatant"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Mathematical Formulation"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Mathematical Formulation"]["ID"]["uri"]}',
            "prefix": "ME"
        },
        f'{BASE_URI}{questions["Research Problem"]["RFRelatant"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Research Field"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Research Field"]["ID"]["uri"]}',
            "prefix": "AD"
        },
        f'{BASE_URI}{questions["Mathematical Model"]["RPRelatant"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Research Problem"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Research Problem"]["ID"]["uri"]}',
            "prefix": "RP"
        },
        f'{BASE_URI}{questions["Mathematical Model"]["TRelatant"]["uri"]}': {
            "question_set": f'{BASE_URI}{questions["Task"]["uri"]}',
            "question_id": f'{BASE_URI}{questions["Task"]["ID"]["uri"]}',
            "prefix": "CT"
        }
    }
    return uri_prefix_map

Utils

Utility functions for assembling model-entity data structures.

Provides helpers that map raw SPARQL result fields to the structured dicts expected by handler and worker code when building model documentation entries.

Provides:

  • get_data_properties — return the list of data-property keys for a given entity type
  • build_quantity_info — construct a quantity/quantity-kind info dict from raw data
  • map_entity_quantity — map an entity's quantity fields using the appropriate property list

build_quantity_info(quantity, qtype)

Build the Info sub-dict for a Quantity or QuantityKind element.

Parameters:

Name Type Description Default
quantity

Answer sub-dict for a single quantity/quantity-kind entry.

required
qtype

Entity class string — "Quantity" or "Quantity Kind". Quantity entries additionally receive QKName and QKID fields pointing to their associated Quantity Kind.

required

Returns:

Type Description

Dict with keys "Type", "Name", "Description", "ID",

and (for Quantity only) "QKName" and "QKID".

Source code in MaRDMO/model/utils.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def build_quantity_info(quantity, qtype):
    '''Build the ``Info`` sub-dict for a Quantity or QuantityKind element.

    Args:
        quantity: Answer sub-dict for a single quantity/quantity-kind entry.
        qtype:    Entity class string — ``"Quantity"`` or ``"Quantity Kind"``.
                  Quantity entries additionally receive ``QKName`` and ``QKID``
                  fields pointing to their associated Quantity Kind.

    Returns:
        Dict with keys ``"Type"``, ``"Name"``, ``"Description"``, ``"ID"``,
        and (for Quantity only) ``"QKName"`` and ``"QKID"``.
    '''
    base_info = {
        "Type": qtype,
        "Name": quantity.get("Name", ""),
        "Description": quantity.get("Description", ""),
        "ID": quantity.get("ID", ""),
    }

    # Only Quantity has QKRelatant
    if qtype == "Quantity":
        base_info["QKName"] = quantity.get("QKRelatant-Q", {}).get(0, {}).get(0, {}).get("Name", "")
        base_info["QKID"] = quantity.get("QKRelatant-Q", {}).get(0, {}).get(0, {}).get("ID", "")

    return base_info

get_data_properties(item_type)

Return a URL→QID mapping of data properties for the given item_type.

Combines class-independent properties (the same for all entity types) with class-dependent properties whose Wikibase item QID is suffixed with the item_type string (e.g. "linear model""linear quantity").

Parameters:

Name Type Description Default
item_type

Entity class string, e.g. "model", "task", "quantity", or "quantity kind".

required

Returns:

Type Description

Dict mapping MathModDB property URL to Wikibase item QID.

Source code in MaRDMO/model/utils.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def get_data_properties(item_type):
    """Return a URL→QID mapping of data properties for the given *item_type*.

    Combines class-independent properties (the same for all entity types) with
    class-dependent properties whose Wikibase item QID is suffixed with the
    *item_type* string (e.g. ``"linear model"`` → ``"linear quantity"``).

    Args:
        item_type: Entity class string, e.g. ``"model"``, ``"task"``,
                   ``"quantity"``, or ``"quantity kind"``.

    Returns:
        Dict mapping MathModDB property URL to Wikibase item QID.
    """

    # Get MathModDB Mapping and Items
    mathmoddb = get_mathmoddb()
    items = get_items()

    # Add class-independent Properties
    properties = {
        mathmoddb.get(key=k)["url"]: items.get(label)
        for k, label in INDEPENDENT_PROPERTIES
    }

    # Add class-dependent Properties
    properties.update({
        mathmoddb.get(key=k)["url"]: items.get(f'{label} {item_type}')
        for k, label in DEPENDENT_PROPERTIES
    })

    return properties

map_entity_quantity(data, entity_type)

Attach Quantity/QuantityKind Info dicts to matching formula elements.

For each entity of entity_type in data, matches each element's "quantity" name against the top-level "quantity" section and writes a "Info" key (built by :func:build_quantity_info) when a match is found.

Parameters:

Name Type Description Default
data

Top-level answers dict (mutated in place).

required
entity_type

Key of the entity section to process (e.g. "formulation" or "task").

required
Source code in MaRDMO/model/utils.py
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def map_entity_quantity(data, entity_type):
    '''Attach Quantity/QuantityKind ``Info`` dicts to matching formula elements.

    For each entity of *entity_type* in *data*, matches each element's
    ``"quantity"`` name against the top-level ``"quantity"`` section and
    writes a ``"Info"`` key (built by :func:`build_quantity_info`) when a
    match is found.

    Args:
        data:        Top-level answers dict (mutated in place).
        entity_type: Key of the entity section to process (e.g.
                     ``"formulation"`` or ``"task"``).
    '''
    for entity in data.get(entity_type, {}).values():
        for element in entity.get("element", {}).values():
            element_quantity_name = element.get("quantity", {}).get("Name", "").lower()

            for quantity in data.get("quantity", {}).values():
                quantity_name = quantity.get("Name", "").lower()

                if element_quantity_name != quantity_name:
                    continue

                qtype = quantity.get("QorQK")

                if qtype in ('Quantity', 'Quantity Kind'):
                    element["Info"] = build_quantity_info(quantity, qtype)