Projet : étape 4.2
Strates

Buts: Modéliser des différentes «couches» de cellules d'un fragment d'organe.

Préambule

Comme évoqué précédemment, un Organ va être discretisé et vu comme une grille carrée. Nous allons donc, à partir de maintenant, devoir travailler avec deux types de coordonnées :

Pour commencer, dotez la classe Organ :

Empilement

Comme nous l'avons vu dans le decriptif général de cette partie, chaque case de la grille doit pouvoir superposer jusqu'à trois niveaux de cellules différentes : une cellule de type «ECM», une de type «organe» et une de type «réseau sanguin». L'idée générale est qu'une cellule sanguine peut reposer sur une cellule du organe qui elle même repose sur une cellule de l'ECM.

Une case aura donc :

Dans ce qui suit, nous vous suggérons d'introduire :

Chaque case de la grille discretisant la vue interne correspondra donc à une instance de CellsLayer (nous y reviendrons un peu plus loin).

Hiérarchie de cellules

Nous allons commencer par matérialiser la notion de cellule en créant une classe Cell dont dériveront trois sous-classes : ECMCell, OrganCell et BloodCell (dont chacune correspondra à un des niveaux mentionnés plus haut).

Chacun de ces niveaux va véhiculer des substances (et donc être associé à un objet de type Substance). Ceci permet de modéliser les flèches rouges du schéma déjà donné dans le descriptif général:

empilement de cellules

Comme une cellule peut aussi ne véhiculer aucune substance, il est judicieux de modéliser la substance associée à un Cell comme un pointeur (un Substance* qui vaudra nullptr lorsqu'aucune substance n'est véhiculée par la cellule).

Pour faire en sorte qu'il y ait un échange entre un niveau et un autre (flèches bleues), il faudra gérer le passage d'une fraction de produit d'un niveau à l'autre.

Exemple concret: supposons qu'une case [i][j] superpose une ECMCell véhiculant la Substance s1 et une OrganCell véhiculant la Substance s2 . On peut imaginer par exemple que s1 contient une quantité q1 de glucose et que s2 contient une quantité q2 du même produit. Pour matérialiser le fait que la OrganCell consomme une quantité q de glucose depuis la ECMCell on va simplement débiter s1 d'une quantité q de glucose (q1 = q1 - q) et ajouter à s2 cette même quantité de glucose (q2 = q2 + q).

Ceci devrait rappeler à votre bon souvenir les méthodes codées dans la classe Substance mais nous y reviendrons un plus tard.

A ce stade la hiérarchie des cellules va être très simple car nous ne nous préoccuperons pas encore de l'implémentation de l'échange de substances ou de d'autres mécanismes d'évolution (comme la division des cellules). ECMCell, OrganCell et BloodCell auront donc au terme de cette étape un contenu très proche et très basique.

Les BloodCell pourront représenter soit des cellules sanguines de l'artère, soit des cellules sanguines des capillaires (seules ces dernières pourront diffuser des substances).

La catégorie de la BloodCell (artère ou capillaire) sera modélisée au moyen d'un attribut de type TypeBloodCell fourni dans le fichier Types.hpp.

"Strates" : la classe CellsLayer

Dans la grille utilisée pour modéliser la vue interne, une position logique d'indices [i][j] peut donc voir s'"empiler" jusqu'à trois niveaux de Cell différents. Comme suggéré plus haut, la classe CellsLayer a pour but de "fédérer" et gérer ces différents niveaux.

Un CellsLayer sera ainsi caractérisé par :

Les trois derniers attributs représentent donc les 3 niveaux («ECM», «organe» et «réseau sanguin») présents à une position donnée et que le CellsLayer va gérer.

Par ailleurs, ces trois niveaux pourront diffuser des substances sur les cases avoisinantes. Pour connaitre ces cases, il sera nécessaire de savoir sur quelle vue interne (Organ) elles prennent place. Ceci permettra de savoir par exemple dans quelles limites il existe des cases voisines.

Pour ce qui est des constructeurs, nous vous suggérons (pour être conforme aux tests fournis):

[Question Q4.4] Avec quelle valeur le constructeur de CellsLayer doit il invoquer celui du ECMCell qu'il alloue dynamiquement ?

[Question Q4.5] Que doit faire le destructeur d'un Cell pour éviter les fuites de mémoire ?

Répondez à ces questions dans votre fichier REPONSES et apportez les modifications impliquées à votre code.

Nous vous suggérons également de doter la classe CellsLayer  :

Pour le codage des méthodes suggérées ci-dessus, si vous pensez devoir définir une méthode Cell::getSubstance(), ce qui n'est pas indispensable, elle devrait alors être en accès protégé (seules les sous-classes de Cell devraient pouvoir accéder à la substance qu'elles véhiculent).

[Question Q4.6] Que doit faire le destructeur d'un CellsLayer pour éviter les fuites de mémoire ?

[Question Q4.7] Quelle(s) méthode(s) ajoutez vous et à quelle(s) classe(s) pour permettre le codage de CellsLayer::updateSubstance ?

[Question Q4.8] Quelle(s) méthode(s) ajoutez vous et à quelle(s) classe(s) pour permettre le codage des «getters» sur les quantités de substances véhiculées par chaque niveau d'un CellsLayer ?

[Question Q4.9] Quelle(s) méthode(s) ajoutez vous et à quelle(s) classe(s) pour permettre le codage de CellsLayers::organCellTakeFromEcm ?

Répondez à ces questions dans votre fichier REPONSES en justifiant vos choix et codez les traitements suggérés.

Lien entre Organ et CellsLayer

Dotez donc maintenant la classe Organ d'un attribut de type tableau de CellsLayer (à vous de voir si vous voulez recourir à des pointeurs ou pas). Ce tableau sera carré de taille nbCells x nbCells. Nous le désignerons sous le nom cellsLayers_ dans le reste de l'énoncé (mais vous êtes libre de le nommer autrement).

La méthode Organ::reloadConfig qui est en charge d'initialiser les éléments paramétrables relatifs à l'organe peut initialiser le tableau cellsLayers_ dès qu'elle a connaissance du nombre de lignes dictées par le fichier de configuration.

Vous ferez donc en sorte que cette méthode initialise le tableau cellsLayers_ en le remplissant d'instances CellsLayer n'ayant que le niveau «ECM». On considèrera donc que le niveau ECM est toujours présent a minima. Attention à faire en sorte qu'il s'agisse bien d'instances distinctes!!

Test 21 : Strates

Un test non graphique, Tests/UnitTests/CellsLayerTest.cpp, est mis à votre disposition pour tester l'essentiel des développements de cette étape. Examinez le contenu de ce fichier pour comprendre quels tests sont réalisés. Lancez le test au moyen de la cible cellsLayerTest après avoir pris soin de la décommenter dans le fichier CMakeLists.txt.

Le résultat du test devrait être:

===============================================================================
All tests passed (87 assertions in 4 test cases)

Ici encore, un peu de recul et un petit schéma de synthèse sur «papier» pour avoir une vue d'ensemble seront certainement bénéfiques.

Retour à l'énoncé du projet (partie 4) Module suivant (partie 4.3)