Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/SCKAN-364 - Add statement preview row to the export + persist statement preview suffix and prefix #404

Merged
merged 10 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 2 additions & 48 deletions backend/composer/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
)
from ..services.connections_service import get_complete_from_entities_for_destination, \
get_complete_from_entities_for_via
from ..services.statement_service import create_statement_preview
from ..services.errors_service import get_connectivity_errors
from ..utils import join_entities


# MixIns
Expand Down Expand Up @@ -644,53 +644,7 @@ def get_entities_journey(self, instance):
def get_statement_preview(self, instance):
if 'journey' not in self.context:
self.context['journey'] = instance.get_journey()
return self.create_statement_preview(instance, self.context['journey'])

def create_statement_preview(self, instance, journey):
sex = instance.sex.sex_str if instance.sex else None

species_list = [specie.name for specie in instance.species.all()]
species = join_entities(species_list)
if not species:
species = ""

phenotype = instance.phenotype.phenotype_str if instance.phenotype else ''
origin_names = [origin.name for origin in instance.origins.all()]
origins = join_entities(origin_names)
if not origins:
origins = ""

circuit_type = instance.get_circuit_type_display() if instance.circuit_type else None
projection = instance.get_projection_display() if instance.projection else None
projection_phenotype = str(instance.projection_phenotype) if instance.projection_phenotype else ''

laterality_description = instance.get_laterality_description()

apinatomy = instance.apinatomy_model if instance.apinatomy_model else ""
journey_sentence = '; '.join(journey)

# Creating the statement
if sex or species != "":
statement = f"In {sex or ''} {species}, the {phenotype.lower()} connection goes {journey_sentence}.\n"
else:
statement = f"A {phenotype.lower()} connection goes {journey_sentence}.\n"

statement += f"This "
if projection:
statement += f"{projection.lower()} "
if projection_phenotype:
statement += f"{projection_phenotype.lower()} "
if circuit_type:
statement += f"{circuit_type.lower()} "

statement += f"connection projects from the {origins}."
if laterality_description:
statement = statement[:-1] + f" and is found {laterality_description}.\n"

if apinatomy:
statement += f" It is described in {apinatomy} model."

return statement.strip().replace(" ", " ")
return create_statement_preview(instance, self.context['journey'])

def get_errors(self, instance) -> List:
return get_connectivity_errors(instance)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.1.4 on 2024-12-18 15:59

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("composer", "0067_auto_20241218_0928"),
]

operations = [
migrations.AddField(
model_name="connectivitystatement",
name="statement_prefix",
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name="connectivitystatement",
name="statement_suffix",
field=models.TextField(blank=True, null=True),
),
]
24 changes: 24 additions & 0 deletions backend/composer/migrations/0069_auto_20241218_1659.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 4.1.4 on 2024-12-18 15:59

from .helpers.statement_preview import get_migration_prefix_for_statement_preview, get_migration_suffix_for_statement_preview
from django.db import migrations


def update_suffix_prefix_for_connectivity_statement_fields(apps, schema_editor):
ConnectivityStatement = apps.get_model('composer', 'ConnectivityStatement')
for cs in ConnectivityStatement.objects.all():
cs.statement_prefix = get_migration_prefix_for_statement_preview(cs)
cs.statement_suffix = get_migration_suffix_for_statement_preview(cs)
cs.save(update_fields=["statement_prefix", "statement_suffix"])


class Migration(migrations.Migration):

dependencies = [
("composer", "0068_connectivitystatement_statement_prefix_and_more"),
]

operations = [
migrations.RunPython(
update_suffix_prefix_for_connectivity_statement_fields)
]
Empty file.
60 changes: 60 additions & 0 deletions backend/composer/migrations/helpers/statement_preview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from composer.utils import join_entities
from django.apps import apps


def get_migration_prefix_for_statement_preview(cs) -> str:
sex = cs.sex.name if cs.sex else None

species_list = [
specie.name for specie in cs.species.all()]
species = join_entities(species_list)
if not species:
species = ""

phenotype = cs.phenotype.name if cs.phenotype else ''
if sex or species != "":
statement = f"In {sex or ''} {species}, the {phenotype.lower()} connection goes"
else:
statement = f"A {phenotype.lower()} connection goes"
return statement


def get_migration_suffix_for_statement_preview(cs):
ConnectivityStatement = apps.get_model(
'composer', 'ConnectivityStatement')
connectivity_statement = ConnectivityStatement.objects.get(
id=cs.id)

circuit_type = connectivity_statement.get_circuit_type_display(
) if connectivity_statement.circuit_type else None
projection = connectivity_statement.get_projection_display(
) if connectivity_statement.projection else None
projection_phenotype = str(
connectivity_statement.projection_phenotype) if connectivity_statement.projection_phenotype else ''

laterality_description = connectivity_statement.get_laterality_description()
apinatomy = connectivity_statement.apinatomy_model if connectivity_statement.apinatomy_model else ""

origin_names = [
origin.name for origin in connectivity_statement.origins.all()]
origins = join_entities(origin_names)

if not origins:
origins = ""

statement = f"This "
if projection:
statement += f"{projection.lower()} "
if projection_phenotype:
statement += f"{projection_phenotype.lower()} "
if circuit_type:
statement += f"{circuit_type.lower()} "

statement += f"connection projects from the {origins}."
if laterality_description:
statement = statement[:-1] + \
f" and is found {laterality_description}.\n"

if apinatomy:
statement += f" It is described in {apinatomy} model."
return statement
8 changes: 3 additions & 5 deletions backend/composer/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,6 @@ class Sex(models.Model):
def __str__(self):
return self.name

@property
def sex_str(self):
return str(self.name) if self.name else ''

class Meta:
ordering = ["name"]
verbose_name_plural = "Sex"
Expand Down Expand Up @@ -568,6 +564,8 @@ class ConnectivityStatement(models.Model):
created_date = models.DateTimeField(auto_now_add=True, db_index=True)
modified_date = models.DateTimeField(auto_now=True, db_index=True)
journey_path = models.JSONField(null=True, blank=True)
statement_prefix = models.TextField(null=True, blank=True)
statement_suffix = models.TextField(null=True, blank=True)

def __str__(self):
suffix = ""
Expand Down Expand Up @@ -1030,7 +1028,7 @@ class AlertType(models.Model):

def __str__(self):
return self.name


class StatementAlert(models.Model):
connectivity_statement = models.ForeignKey(
Expand Down
63 changes: 63 additions & 0 deletions backend/composer/services/statement_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from ..utils import join_entities


def get_prefix_for_statement_preview(cs) -> str:
sex = cs.sex.name if cs.sex else None

species_list = [
specie.name for specie in cs.species.all()]
species = join_entities(species_list)
if not species:
species = ""

phenotype = cs.phenotype.name if cs.phenotype else ''
if sex or species != "":
statement = f"In {sex or ''} {species}, the {phenotype.lower()} connection goes"
else:
statement = f"A {phenotype.lower()} connection goes"
return statement


def get_suffix_for_statement_preview(cs):

circuit_type = cs.get_circuit_type_display(
) if cs.circuit_type else None
projection = cs.get_projection_display(
) if cs.projection else None
projection_phenotype = str(
cs.projection_phenotype) if cs.projection_phenotype else ''

laterality_description = cs.get_laterality_description()
apinatomy = cs.apinatomy_model if cs.apinatomy_model else ""

origin_names = [
origin.name for origin in cs.origins.all()]
origins = join_entities(origin_names)

if not origins:
origins = ""

statement = f"This "
if projection:
statement += f"{projection.lower()} "
if projection_phenotype:
statement += f"{projection_phenotype.lower()} "
if circuit_type:
statement += f"{circuit_type.lower()} "

statement += f"connection projects from the {origins}."
if laterality_description:
statement = statement[:-1] + \
f" and is found {laterality_description}.\n"

if apinatomy:
statement += f" It is described in {apinatomy} model."
return statement


def create_statement_preview(cs, journey):
prefix = cs.statement_prefix
journey_sentence = '; '.join(journey)
suffix = cs.statement_suffix
statement = f'{prefix} {journey_sentence}.\n{suffix}'
return statement.strip().replace(" ", " ")
Loading