LCOV - code coverage report
Current view: top level - ugbase/lib_grid/refinement/projectors - neurite_projector.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 74 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 11 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2016:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Markus Breit
       4              :  *
       5              :  * This file is part of UG4.
       6              :  *
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  *
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  *
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  *
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  *
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  *
      32              :  *  Created on: 2016-12-19
      33              :  */
      34              : 
      35              : #ifndef UG__LIB_GRID__REFINEMENT__PROJECTORS__NEURITE_PROJECTOR_H
      36              : #define UG__LIB_GRID__REFINEMENT__PROJECTORS__NEURITE_PROJECTOR_H
      37              : 
      38              : #include "common/types.h"
      39              : #include "lib_grid/refinement/projectors/refinement_projector.h"
      40              : 
      41              : #include <boost/serialization/split_member.hpp> // for separate load/save methods
      42              : 
      43              : namespace ug {
      44              : 
      45              : class NeuriteProjector
      46              : : public RefinementProjector
      47              : {
      48              :         public:
      49              :                 NeuriteProjector();
      50              :                 NeuriteProjector(SPIGeometry3d geometry);
      51              : 
      52              :                 virtual ~NeuriteProjector();
      53              : 
      54              :                 virtual void set_geometry(SPIGeometry3d geometry);
      55              : 
      56              :                 /// called when a new vertex was created from an old vertex
      57              :                 virtual number new_vertex(Vertex* vrt, Vertex* parent);
      58              : 
      59              :                 /// called when a new vertex was created from an old edge
      60              :                 virtual number new_vertex(Vertex* vrt, Edge* parent);
      61              : 
      62              :                 /// called when a new vertex was created from an old face
      63              :                 virtual number new_vertex(Vertex* vrt, Face* parent);
      64              : 
      65              :                 /// called when a new vertex was created from an old volume
      66              :                 virtual number new_vertex(Vertex* vrt, Volume* parent);
      67              : 
      68              :                 /// project a vertex to its model position
      69              :                 void project(Vertex* vrt);
      70              : 
      71              :                 /// spline direction at some grid object
      72              :                 void direction_at_grid_object(vector3& dirOut, GridObject* o) const;
      73              : 
      74              : 
      75              :         protected:
      76              :                 void attach_surf_params();
      77              : 
      78              :         public:
      79              :                 struct Section
      80              :                 {
      81            0 :                         Section() : endParam(0) {}                // constructor for serialization
      82              :                         Section(number _endParam)   // constructor for search with CompareSections
      83            0 :                         : endParam(_endParam) {}
      84              : 
      85              :                         number endParam;
      86              : 
      87              :                         number splineParamsX[4];
      88              :                         number splineParamsY[4];
      89              :                         number splineParamsZ[4];
      90              :                         number splineParamsR[4];
      91              : 
      92              :                         template <class Archive>
      93            0 :                         void serialize(Archive& ar, const unsigned int version)
      94              :                         {
      95            0 :                                 ar & endParam;
      96            0 :                                 for (size_t i = 0; i < 4; ++i)
      97              :                                 {
      98            0 :                                         ar & splineParamsX[i];
      99            0 :                                         ar & splineParamsY[i];
     100            0 :                                         ar & splineParamsZ[i];
     101            0 :                                         ar & splineParamsR[i];
     102              :                                 }
     103            0 :                         }
     104              :                 };
     105              : 
     106              :                 struct BranchingPoint;
     107            0 :                 struct BranchingRegion
     108              :                 {
     109            0 :                         BranchingRegion() : t(0.0), bp(SPNULL) {} // constructor for serialization
     110              :                         BranchingRegion(number _t)       // constructor for search with CompareBranchingPointEnds
     111            0 :                         : t(_t) {}
     112              : 
     113              :                         /// the axial parameter where other neurite(s) branch off
     114              :                         number t;
     115              : 
     116              :                         /// pointer to whole branching point
     117              :                         SmartPtr<BranchingPoint> bp;
     118              : 
     119              :                         template<class Archive>
     120            0 :                         void save(Archive & ar, const unsigned int version) const
     121              :                         {
     122            0 :                                 ar << t;
     123              : 
     124            0 :                                 bool owns_bp = bp->vRegions[0] == this;
     125              :                                 ar << owns_bp;
     126            0 :                                 if (owns_bp)
     127              :                                         ar << *bp;
     128            0 :                         }
     129              : 
     130              :                         template<class Archive>
     131            0 :                         void load(Archive & ar, const unsigned int version)
     132              :                         {
     133              :                                 // invoke serialization of the base class
     134            0 :                                 ar >> t;
     135              : 
     136              :                                 bool owns_bp;
     137              :                                 ar >> owns_bp;
     138            0 :                                 if (owns_bp)
     139              :                                 {
     140            0 :                                         bp = make_sp(new BranchingPoint());
     141              :                                         ar >> *bp;
     142              :                                 }
     143            0 :                         }
     144              : 
     145              :                         BOOST_SERIALIZATION_SPLIT_MEMBER()
     146              :                 };
     147              : 
     148              : 
     149            0 :                 struct BranchingPoint
     150              :                 {
     151              :                         std::vector<uint32_t> vNid;
     152              :                         std::vector<BranchingRegion*> vRegions;
     153              : 
     154              :                         template <class Archive>
     155            0 :                         void serialize(Archive& ar, const unsigned int version)
     156              :                         {
     157              :                                 // please note: We could simply use
     158              :                                 // ar & vNid
     159              :                                 // but this somehow takes up a huge number of template recursions
     160            0 :                                 size_t sz = vNid.size(); // this does not hurt in the load-case
     161              :                                 ar & sz;
     162            0 :                                 vNid.resize(sz);    // this does not hurt in the save-case
     163            0 :                                 for (size_t i = 0; i < sz; ++i)
     164              :                                         ar & vNid[i];
     165            0 :                         }
     166              :                 };
     167              : 
     168              :                 struct SomaPoint {
     169              :                         vector3 soma;
     170              :                         number radius;
     171              :                         SomaPoint(const vector3& soma, number radius) : soma(soma), radius(radius) {}
     172              :                 };
     173              : 
     174            0 :                 struct SomaBranchingRegion {
     175              :                         SmartPtr<SomaPoint> somaPt;
     176              :                         number radius;
     177              :                         vector3 center;
     178              :                         number t;
     179              :                         vector3 bp;
     180              : 
     181              :                         template <class Archive>
     182              :                         void serialize(Archive& ar, const unsigned int version) {
     183            0 :                                 ar & radius;
     184            0 :                                 ar & t;
     185              :                         }
     186              : 
     187              :                         template<class Archive>
     188              :                         void load(Archive & ar, const unsigned int version)
     189              :                         {
     190              :                                 ar >> radius;
     191              :                                 ar >> t;
     192              :                         }
     193              : 
     194              :                         SomaBranchingRegion(const vector3& center, number radius, number t)
     195              :                                   : radius(radius),
     196              :                                   t(t),
     197              :                                   bp(center)
     198              :                         {}
     199              : 
     200              :                         SomaBranchingRegion(number t)
     201            0 :                                  : radius(-1),
     202            0 :                                   t(t)
     203              :                         {}
     204              : 
     205              :                         SomaBranchingRegion()
     206            0 :                                  : radius(-1),
     207            0 :                                   t(-1)
     208              :                         {}
     209              :                 };
     210              : 
     211              :                 /*!
     212              :                  * \brief Mapping of model to surface vertices
     213              :                  */
     214              :                 struct Mapping {
     215              :                         /// TODO: Mapping should store unique indices of 1d vertices from SWC file
     216              :                         vector3 v1; /// start vertex of edge
     217              :                         vector3 v2; /// end vertex of edge
     218              :                         number lambda; /// projection parameter lambda
     219              :                 };
     220              : 
     221              :                 struct Neurite
     222              :                 {
     223              :                         vector3 refDir;
     224              :                         std::vector<Section> vSec;
     225              :                         std::vector<BranchingRegion> vBR;
     226              :                         std::vector<Section> vSomaSec;
     227              :                         std::vector<SomaBranchingRegion> vSBR;
     228              : 
     229              :                         template <class Archive>
     230            0 :                         void serialize(Archive& ar, const unsigned int version)
     231              :                         {
     232              :                                 /// neurite information
     233            0 :                                 ar & refDir;
     234              : 
     235            0 :                                 size_t sz = vSec.size();
     236              :                                 ar & sz;
     237            0 :                                 vSec.resize(sz);
     238            0 :                                 for (size_t i = 0; i < sz; ++i)
     239              :                                         ar & vSec[i];
     240              : 
     241            0 :                                 sz = vBR.size();
     242              :                                 ar & sz;
     243            0 :                                 vBR.resize(sz);
     244            0 :                                 for (size_t i = 0; i < sz; ++i)
     245              :                                         ar & vBR[i];
     246              : 
     247              :                                 /// soma information
     248            0 :                                 sz = vSomaSec.size();
     249              :                                 ar & sz;
     250            0 :                                 vSomaSec.resize(sz);
     251            0 :                                 for (size_t i = 0; i < sz; ++i)
     252              :                                         ar & vSomaSec[i];
     253              : 
     254            0 :                                 sz = vSBR.size();
     255              :                                 ar & sz;
     256            0 :                                 vSBR.resize(sz);
     257            0 :                                 for (size_t i = 0; i < sz; ++i) {
     258              :                                         ar & vSBR[i];
     259              :                                 }
     260            0 :                         }
     261              :                 };
     262              : 
     263              :                 struct SurfaceParams
     264              :                 {
     265              :                         /**
     266              :                          * @brief Neurite ID a vertex belongs to
     267              :                          *
     268              :                          * Only the low 20 bits are used for ordinary vertices, i.e.,
     269              :                          * vertices that do not belong to two neurites at a branching point.
     270              :                          * In branching points, the high 4 bits encode which of the child
     271              :                          * neurites share the vertex: bit 28 for child 0, bit 29 for child 1,
     272              :                          * bit 30 for child 2 and bit 31 for child 3.
     273              :                          * Bits 20-27 are used to encode the branching region on the parent
     274              :                          * neurite.
     275              :                          * There cannot be more than 256 branching regions per neurite.
     276              :                          * There cannot be more than 4 children per branching point.
     277              :                          */
     278              :                         uint32 neuriteID;
     279              :                         float axial;
     280              :                         float angular;
     281              :                         float radial;
     282              :                 };
     283              : 
     284              : 
     285              :         public:
     286              :                 struct CompareSections
     287              :                 {
     288              :                         bool operator()(const Section& a, const Section& b)
     289            0 :                         {return a.endParam < b.endParam;}
     290              :                 };
     291              :                 struct CompareBranchingRegionEnds
     292              :                 {
     293              :                         bool operator()(const BranchingRegion& a, const BranchingRegion& b)
     294            0 :                         {return a.t < b.t;}
     295              :                 };
     296              : 
     297              :                 // helper struct for branching point calculations
     298              :                 struct BPProjectionHelper
     299              :                 {
     300              :                         number start;
     301              :                         number end;
     302              :                         std::vector<Section>::const_iterator sec_start;
     303              :                         const SomaBranchingRegion* sr;
     304              :                 };
     305              : 
     306              :                 void debug_neurites() const;
     307              : 
     308              :                 struct CompareSomaBranchingRegionsEnd {
     309              :                         bool operator()(const SomaBranchingRegion& a, const SomaBranchingRegion& b) {
     310            0 :                                 return a.t < b.t;
     311              :                         }
     312              :                 };
     313              : 
     314              :         public:
     315              :                 std::vector<Neurite>& neurites();
     316              :                 std::vector<SomaBranchingRegion>& somata();
     317              :                 const Neurite& neurite(uint32_t nid) const;
     318              :                 Grid::VertexAttachmentAccessor<Attachment<SurfaceParams> >& surface_params_accessor();
     319              :                 const Grid::VertexAttachmentAccessor<Attachment<SurfaceParams> >& surface_params_accessor() const;
     320              :                 const std::vector<std::pair<number, number> >& quadrature_points() const;
     321              :                 void average_pos_from_parent(vector3& posOut, const IVertexGroup* const parent) const;
     322              :                 vector3 position(Vertex* vrt) const;
     323              : 
     324              :                 number axial_range_around_branching_region
     325              :                 (
     326              :                         uint32_t nid,
     327              :                         size_t brInd,
     328              :                         number numberOfRadii = 5.0
     329              :                 ) const;
     330              : 
     331              :                 number axial_range_around_soma_region
     332              :                 (
     333              :                         const SomaBranchingRegion& sr,
     334              :                         size_t numRadii,
     335              :                         size_t nid,
     336              :                         Vertex* vrt
     337              :                 ) const;
     338              : 
     339              :                 bool is_in_axial_range_around_soma_region
     340              :                 (
     341              :                         const SomaBranchingRegion& sr,
     342              :                         size_t nid,
     343              :                         Vertex* vrt
     344              :                 ) const;
     345              : 
     346              :                 void print_surface_params(const Vertex* const v) const;
     347              : 
     348              :         protected:
     349              :                 std::vector<Section>::const_iterator get_section_iterator(uint32_t nid, float t) const;
     350              :                 std::vector<NeuriteProjector::Section>::const_iterator get_soma_section_iterator(uint32_t nid, float t) const;
     351              : 
     352              :                 void prepare_quadrature();
     353              : 
     354              :                 void average_params
     355              :                 (
     356              :                         uint32_t& neuriteID,
     357              :                         float& t,
     358              :                         float& angle,
     359              :                         float& radius,
     360              :                         const IVertexGroup* parent
     361              :                 ) const;
     362              : 
     363              :                 number push_into_place(Vertex* vrt, const IVertexGroup* parent);
     364              : 
     365              :         private:
     366              :                 Attachment<SurfaceParams> m_aSurfParams;
     367              :                 Grid::VertexAttachmentAccessor<Attachment<SurfaceParams> > m_aaSurfParams;
     368              : 
     369              :                 /**
     370              :                  * @brief storage for cubic splines:
     371              :                  * Vector of sorted vectors of sections; each inner vector represents a single neurite.
     372              :                  * Any complete neurite is parameterized by t in [0,1]. Each section in the neurite vector
     373              :                  * consists of the parameter t at which the section ends and the sixteen coefficients
     374              :                  * describing the spline in each dimension (monomial basis {(t_(i+1) - t)^i}_i).
     375              :                 **/
     376              :                 std::vector<Neurite> m_vNeurites; //!< spline information for neurites
     377              : 
     378              :                 std::vector<std::pair<number, number> > m_qPoints; //!< for quadrature when projecting within branching points
     379              : 
     380              :                 /*!
     381              :                  * \brief check if an element is inside a sphere
     382              :                  * \param[in] elem
     383              :                  * \param[in] center
     384              :                  * \param[in] radius
     385              :                  * \return \c true if element is inside or on sphere else false
     386              :                  */
     387              :                 template <class TElem>
     388            0 :                 bool IsElementInsideSphere
     389              :                 (
     390              :                         const TElem* elem,
     391              :                         const ug::vector3& center,
     392              :                         const number radius
     393              :                 ) const
     394              :                 {
     395            0 :                         Grid::VertexAttachmentAccessor<APosition> aaPos(this->geometry()->grid(), aPosition);
     396              :                         vector3 c = CalculateCenter(elem, aaPos);
     397              :                         vector3 diff;
     398              :                         VecSubtract(diff, c, center);
     399              :                         VecPow(diff, diff, 2.0);
     400            0 :                         number s = diff.x() + diff.y() + diff.z();
     401            0 :                         return (s <= (sq(radius) + SMALL));
     402              :                 }
     403              : 
     404              :                 friend class boost::serialization::access;
     405              :                 template<class Archive>
     406            0 :                 void save(Archive & ar, const unsigned int version) const
     407              :                 {
     408              :                         UG_EMPTY_BASE_CLASS_SERIALIZATION(NeuriteProjector, RefinementProjector);
     409              : 
     410              :                         // only write if data is to be written
     411              :                         if(ArchiveInfo<Archive>::TYPE == AT_DATA)
     412              :                         {
     413              :                                 // neurites
     414            0 :                                 size_t sz = m_vNeurites.size();
     415              :                                 ar << sz;
     416            0 :                                 for (size_t i = 0; i < sz; ++i) {
     417              :                                         ar << m_vNeurites[i];
     418              :                                 }
     419              :                         }
     420              : 
     421              :                         // do not do anything otherwise
     422              :                         else if (ArchiveInfo<Archive>::TYPE == AT_GUI)
     423              :                         {}
     424            0 :                 }
     425              : 
     426              :                 template<class Archive>
     427            0 :                 void load(Archive & ar, const unsigned int version)
     428              :                 {
     429              :                         UG_EMPTY_BASE_CLASS_SERIALIZATION(NeuriteProjector, RefinementProjector);
     430              : 
     431              :                         // neurites
     432              :                         size_t sz;
     433              :                         ar >> sz;
     434            0 :                         m_vNeurites.resize(sz);
     435            0 :                         for (size_t i = 0; i < sz; ++i) {
     436              :                                 ar >> m_vNeurites[i];
     437              :                         }
     438              : 
     439              :                         // reconstruct uninitialized pointers in branching points/ranges
     440              :                         size_t nNeurites = m_vNeurites.size();
     441            0 :                         for (size_t n = 0; n < nNeurites; ++n)
     442              :                         {
     443              :                                 Neurite& neurite = m_vNeurites[n];
     444              :                                 size_t nBR = neurite.vBR.size();
     445            0 :                                 for (size_t b = 0; b < nBR; ++b)
     446              :                                 {
     447              :                                         BranchingRegion& br = neurite.vBR[b];
     448              :                                         SmartPtr<BranchingPoint> bp = br.bp;
     449            0 :                                         if (bp.valid() && !bp->vRegions.size())
     450              :                                         {
     451              :                                                 size_t nReg = bp->vNid.size();
     452            0 :                                                 bp->vRegions.resize(nReg);
     453            0 :                                                 bp->vRegions[0] = &br;
     454            0 :                                                 for (size_t r = 1; r < nReg; ++r)
     455              :                                                 {
     456              :                                                         UG_ASSERT(m_vNeurites[bp->vNid[r]].vBR.size(),
     457              :                                                                 "No branching region in neurite where there should be one.")
     458            0 :                                                         bp->vRegions[r] = &m_vNeurites[bp->vNid[r]].vBR[0];
     459            0 :                                                         bp->vRegions[r]->bp = bp;
     460              :                                                 }
     461              :                                         }
     462              :                                 }
     463              :                         }
     464              :                         // debug_neurites();
     465            0 :                 }
     466              :                 BOOST_SERIALIZATION_SPLIT_MEMBER()
     467              : };
     468              : 
     469              : // DO NOT CHANGE LINES BELOW! Needed for serialization! //
     470              : std::ostream& operator<<(std::ostream& os, const NeuriteProjector::SurfaceParams& surfParams);
     471              : std::istream& operator>>(std::istream& in, NeuriteProjector::SurfaceParams& surfParams);
     472              : DECLARE_ATTACHMENT_INFO_TRAITS(Attachment<NeuriteProjector::SurfaceParams>, "NeuriteProjectorSurfaceParams");
     473              : std::ostream& operator<<(std::ostream& os, const NeuriteProjector::Mapping&  mapping);
     474              : std::istream& operator>>(std::istream& in, NeuriteProjector::Mapping& mapping);
     475              : DECLARE_ATTACHMENT_INFO_TRAITS(Attachment<NeuriteProjector::Mapping>, "Mapping");
     476              : } // namespace ug
     477              : 
     478              : #endif // UG__LIB_GRID__REFINEMENT__PROJECTORS__NEURITE_PROJECTOR_H
        

Generated by: LCOV version 2.0-1