LCOV - code coverage report
Current view: top level - models/abm - person.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 51 51 100.0 %
Date: 2024-11-18 12:45:26 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /* 
       2             : * Copyright (C) 2020-2024 MEmilio
       3             : *
       4             : * Authors: Daniel Abele, Elisabeth Kluth, David Kerkmann, Khoa Nguyen
       5             : *
       6             : * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
       7             : *
       8             : * Licensed under the Apache License, Version 2.0 (the "License");
       9             : * you may not use this file except in compliance with the License.
      10             : * You may obtain a copy of the License at
      11             : *
      12             : *     http://www.apache.org/licenses/LICENSE-2.0
      13             : *
      14             : * Unless required by applicable law or agreed to in writing, software
      15             : * distributed under the License is distributed on an "AS IS" BASIS,
      16             : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      17             : * See the License for the specific language governing permissions and
      18             : * limitations under the License.
      19             : */
      20             : #ifndef MIO_ABM_PERSON_H
      21             : #define MIO_ABM_PERSON_H
      22             : 
      23             : #include "abm/infection.h"
      24             : #include "abm/infection_state.h"
      25             : #include "abm/location_id.h"
      26             : #include "abm/location.h"
      27             : #include "abm/location_type.h"
      28             : #include "abm/parameters.h"
      29             : #include "abm/person_id.h"
      30             : #include "abm/personal_rng.h"
      31             : #include "memilio/io/default_serialize.h"
      32             : #include "abm/time.h"
      33             : #include "abm/test_type.h"
      34             : #include "abm/protection_event.h"
      35             : #include "abm/intervention_type.h"
      36             : #include "abm/mask.h"
      37             : #include "abm/mobility_data.h"
      38             : #include "memilio/epidemiology/age_group.h"
      39             : #include "memilio/utils/random_number_generator.h"
      40             : 
      41             : namespace mio
      42             : {
      43             : namespace abm
      44             : {
      45             : 
      46             : static constexpr uint32_t INVALID_PERSON_ID = std::numeric_limits<uint32_t>::max();
      47             : 
      48             : /**
      49             :  * @brief Agents in the simulated Model that can carry and spread the Infection.
      50             :  */
      51             : class Person
      52             : {
      53             : public:
      54             :     /**
      55             :      * @brief Create a Person.
      56             :      * @param[in, out] rng RandomNumberGenerator.
      57             :      * @param[in, out] location Initial Location of the Person.
      58             :      * @param[in] age The AgeGroup of the Person.
      59             :      * @param[in] person_id Index of the Person.
      60             :      */
      61             :     explicit Person(mio::RandomNumberGenerator& rng, LocationType location_type, LocationId location_id, AgeGroup age,
      62             :                     PersonId person_id = PersonId::invalid_id());
      63             : 
      64             :     explicit Person(const Person& other, PersonId id);
      65             : 
      66             :     /**
      67             :      * @brief Compare two Person%s.
      68             :      */
      69             :     bool operator==(const Person& other) const
      70             :     {
      71             :         return (m_person_id == other.m_person_id);
      72             :     }
      73             : 
      74             :     /**
      75             :      * @brief Get the latest #Infection of the Person.
      76             :      * @return The latest #Infection of the Person.
      77             :      */
      78             :     Infection& get_infection();
      79             :     const Infection& get_infection() const;
      80             : 
      81             :     /**
      82             :      * @brief Get all vaccinations of the Person.
      83             :      * @return A vector with all vaccinations.
      84             :      * @{
      85             :      */
      86             :     std::vector<ProtectionEvent>& get_vaccinations()
      87             :     {
      88             :         return m_vaccinations;
      89             :     }
      90             : 
      91             :     const std::vector<ProtectionEvent>& get_vaccinations() const
      92             :     {
      93             :         return m_vaccinations;
      94             :     }
      95             :     /** @} */
      96             : 
      97             :     /**
      98             :      * @brief Returns if the Person is infected at the TimePoint.
      99             :      * @param[in] t TimePoint of querry. Usually the current time of the Simulation.
     100             :      * @return True if the Person is infected at the TimePoint.
     101             :      */
     102             :     bool is_infected(TimePoint t) const;
     103             : 
     104             :     /**
     105             :      * @brief Get the InfectionState of the Person at a specific TimePoint.
     106             :      * @param[in] t TimePoint of querry. Usually the current time of the Simulation.
     107             :      * @return The InfectionState of the latest Infection at time t.
     108             :      */
     109             :     InfectionState get_infection_state(TimePoint t) const;
     110             : 
     111             :     /**
     112             :      * @brief Adds a new Infection to the list of Infection%s.
     113             :      * @param[in] inf The new Infection.
     114             :      */
     115             :     void add_new_infection(Infection&& inf);
     116             : 
     117             :     /**
     118             :      * @brief Get the AgeGroup of this Person.
     119             :      * @return AgeGroup of the Person.
     120             :      */
     121       10035 :     AgeGroup get_age() const
     122             :     {
     123       10035 :         return m_age;
     124             :     }
     125             : 
     126             :     /**
     127             :      * @brief Get the current Location of the Person.
     128             :      * @return Current Location of the Person.
     129             :      */
     130             :     LocationId get_location() const;
     131             : 
     132       10701 :     LocationType get_location_type() const
     133             :     {
     134       10701 :         return m_location_type;
     135             :     }
     136             : 
     137             :     /**
     138             :      * @brief Change the location of the person.
     139             :      * @param[in] id The new location.
     140             :      */
     141             :     void set_location(LocationType type, LocationId id);
     142             : 
     143             :     /**
     144             :      * @brief Get the time the Person has been at its current Location.
     145             :      * @return TimeSpan the Person has been at the Location.
     146             :      */
     147          81 :     TimeSpan get_time_at_location() const
     148             :     {
     149          81 :         return m_time_at_location;
     150             :     }
     151             : 
     152             :     /**
     153             :      * @brief Add to the time the Person has been at its current Location.
     154             :      * @param[in] dt TimeSpan the Person has spent at the Location.
     155             :      */
     156        2844 :     void add_time_at_location(const TimeSpan dt)
     157             :     {
     158        2844 :         m_time_at_location += dt;
     159        2844 :     }
     160             : 
     161             :     /**
     162             :      * @brief Set an assigned Location of the Person.
     163             :      *
     164             :      * Important: Setting incorrect values will cause issues during simulation. It is preferable to use
     165             :      *            Model::assign_location with a valid LocationId, obtained e.g. through Model::add_location.
     166             :      *
     167             :      * The assigned Location is saved by the index of its LocationId. Assume that a Person has at most one assigned
     168             :      * Location of a certain #LocationType.
     169             :      * @param[in] type The LocationType of the Location.
     170             :      * @param[in] id The LocationId of the Location.
     171             :      */
     172             :     void set_assigned_location(LocationType type, LocationId id);
     173             : 
     174             :     /**
     175             :      * @brief Returns the index of an assigned Location of the Person.
     176             :      * Assume that a Person has at most one assigned Location of a certain #LocationType.
     177             :      * @param[in] type #LocationType of the assigned Location.
     178             :      * @return The index in the LocationId of the assigned Location.
     179             :      */
     180             :     LocationId get_assigned_location(LocationType type) const;
     181             : 
     182             :     /**
     183             :      * @brief Get the assigned Location%s of the Person.
     184             :      * @return A vector with the indices of the assigned Location%s of the Person.
     185             :      */
     186             :     const std::vector<LocationId>& get_assigned_locations() const
     187             :     {
     188             :         return m_assigned_locations;
     189             :     }
     190             : 
     191             :     /**
     192             :      * @brief Draw if the Person goes to work or is in home office during lockdown at a specific TimePoint.
     193             :      * Every Person has a random number. Depending on this number and the time, the Person works from home in case of a
     194             :      * lockdown.
     195             :      * @param[in] t The TimePoint of interest. Usually the current time of the Simulation.
     196             :      * @param[in] params Parameters that describe the mobility between Location%s.
     197             :      * @return True the Person works from home.
     198             :      */
     199             :     bool goes_to_work(TimePoint t, const Parameters& params) const;
     200             : 
     201             :     /**
     202             :      * @brief Draw at what time the Person goes to work.
     203             :      * Every Person has a random number to determine what time to go to work.
     204             :      * Depending on this number Person decides what time has to go to work.
     205             :      * @param[in] params Parameters that describe the mobility between Location%s.
     206             :      * @return The time of going to work.
     207             :      */
     208             :     TimeSpan get_go_to_work_time(const Parameters& params) const;
     209             : 
     210             :     /**
     211             :      * @brief Draw if the Person goes to school or stays at home during lockdown.
     212             :      * Every Person has a random number that determines if they go to school in case of a lockdown.
     213             :      * @param[in] t The TimePoint of interest. Usually the current time of the Simulation.
     214             :      * @param[in] params Parameters that describe the mobility between Location%s.
     215             :      * @return True if the Person goes to school.
     216             :      */
     217             :     bool goes_to_school(TimePoint t, const Parameters& params) const;
     218             : 
     219             :     /**
     220             :      * @brief Draw at what time the Person goes to work.
     221             :      * Every Person has a random number to determine what time to go to school.
     222             :      * Depending on this number Person decides what time has to go to school.
     223             :      * @param[in] params Parameters that describe the mobility between Location%s.
     224             :      * @return The time of going to school.
     225             :      */
     226             :     TimeSpan get_go_to_school_time(const Parameters& params) const;
     227             : 
     228             :     /**
     229             :      * @brief Answers the question if a Person is currently in quarantine.
     230             :      * If a Person is in quarantine this Person cannot change to Location%s other than Home or the Hospital.
     231             :      * @param[in] t The TimePoint of interest. Usually the current time of the Simulation.
     232             :      * @param[in] params Parameter that includes the length of a quarantine.
     233             :      * @return True if the Person is in quarantine.
     234             :      */
     235        1647 :     bool is_in_quarantine(TimePoint t, const Parameters& params) const
     236             :     {
     237        1647 :         return t < m_home_isolation_start + params.get<mio::abm::QuarantineDuration>();
     238             :     }
     239             : 
     240             :     /**
     241             :      * @brief Removes the quarantine status of the Person.
     242             :      */
     243             :     void remove_quarantine();
     244             : 
     245             :     /**
     246             :      * @brief Simulates a viral test and returns the test result of the Person.
     247             :      * If the test is positive, the Person has to quarantine.
     248             :      * If the test is negative, quarantine ends.
     249             :      * @param[inout] rng RandomNumberGenerator of the Person.
     250             :      * @param[in] t TimePoint of the test.
     251             :      * @param[in] params Sensitivity and specificity of the test method.
     252             :      * @return True if the test result of the Person is positive.
     253             :      */
     254             :     bool get_tested(PersonalRandomNumberGenerator& rng, TimePoint t, const TestParameters& params);
     255             : 
     256             :     /**
     257             :      * @brief Get the PersonId of the Person.
     258             :      * The PersonId should correspond to the index in m_persons in the Model.
     259             :      * @return The PersonId.
     260             :      */
     261             :     PersonId get_id() const;
     262             : 
     263             :     /**
     264             :      * @brief Get index of Cell%s of the Person.
     265             :      * @return A vector of all Cell indices the Person visits at the current Location.
     266             :      */
     267             :     std::vector<uint32_t>& get_cells();
     268             : 
     269             :     const std::vector<uint32_t>& get_cells() const;
     270             : 
     271             :     /**
     272             :      * @brief Get the current Mask of the Person.
     273             :      * @return Reference to the Mask object of the Person.
     274             :      */
     275          90 :     Mask& get_mask()
     276             :     {
     277          90 :         return m_mask;
     278             :     }
     279             : 
     280             :     const Mask& get_mask() const
     281             :     {
     282             :         return m_mask;
     283             :     }
     284             : 
     285             :     /**
     286             :      * @brief Get the protection of the Mask.
     287             :      * A value of 1 represents full protection and a value of 0 means no protection. This depends on the MaskType of the
     288             :      * Mask the Person is wearing.
     289             :      * @param[in] params The parameters of the Infection that are the same everywhere within the Model.
     290             :      * @return The reduction factor of getting an Infection when wearing the Mask.
     291             :      */
     292             :     ScalarType get_mask_protective_factor(const Parameters& params) const;
     293             : 
     294             :     /**
     295             :      * @brief For every #InterventionType a Person has a compliance value between 0 and 1.
     296             :      * 0 means that the Person never complies to the Intervention.
     297             :      * 1 means that the Person always complies to the Intervention.
     298             :      * @param[in] intervention_type The #InterventionType.
     299             :      * @param[in] value The compliance value.
     300             :      */
     301         216 :     void set_compliance(InterventionType intervention_type, ScalarType value)
     302             :     {
     303         216 :         m_compliance[static_cast<uint32_t>(intervention_type)] = value;
     304         216 :     }
     305             : 
     306             :     /**
     307             :      * @brief Get the compliance of the Person for an Intervention.
     308             :      * @param[in] intervention_type The #InterventionType.
     309             :      * @return The probability that the Person complies to an Intervention.
     310             :      */
     311         666 :     ScalarType get_compliance(InterventionType intervention_type) const
     312             :     {
     313         666 :         return m_compliance[static_cast<uint32_t>(intervention_type)];
     314             :     }
     315             : 
     316             :     /**
     317             :      * @brief Checks whether the Person complies an Intervention.
     318             :      * @param[inout] rng PersonalRandomNumberGenerator of the Person.
     319             :      * @param[in] intervention The #InterventionType.
     320             :      * @return Checks whether the Person complies an Intervention.
     321             :      */
     322             :     bool is_compliant(PersonalRandomNumberGenerator& rng, InterventionType intervention) const;
     323             : 
     324             :     /**
     325             :      * @brief Change the mask to new type.
     326             :      * @param[in] type The required #MaskType.
     327             :      * @param[in] t The TimePoint of mask change.
     328             :      */
     329             :     void set_mask(MaskType type, TimePoint t);
     330             : 
     331             :     /**
     332             :      * @brief Get the multiplicative factor on how likely an #Infection is due to the immune system.
     333             :      * @param[in] t TimePoint of check.
     334             :      * @param[in] virus VirusVariant to check
     335             :      * @param[in] params Parameters in the model.
     336             :      * @returns Protection factor for general #Infection of the immune system to the given VirusVariant at the given TimePoint.
     337             :      */
     338             :     ScalarType get_protection_factor(TimePoint t, VirusVariant virus, const Parameters& params) const;
     339             : 
     340             :     /**
     341             :      * @brief Add a new vaccination
     342             :      * @param[in] v ProtectionType (i. e. vaccine) the person takes.
     343             :      * @param[in] t TimePoint of the vaccination.
     344             :      */
     345          18 :     void add_new_vaccination(ProtectionType v, TimePoint t)
     346             :     {
     347          18 :         m_vaccinations.push_back(ProtectionEvent(v, t));
     348          18 :     }
     349             : 
     350             :     /**
     351             :      * @brief Get the transport mode the Person used to get to its current Location.
     352             :      * @return TransportMode the Person used to get to its current Location.
     353             :      */
     354        1377 :     mio::abm::TransportMode get_last_transport_mode() const
     355             :     {
     356        1377 :         return m_last_transport_mode;
     357             :     }
     358             : 
     359             :     /**
     360             :      * @brief Set the transport mode the Person used to get to its current Location.
     361             :      * @param[in] mode TransportMode the Person used to get to its current Location.
     362             :      */
     363         351 :     void set_last_transport_mode(const mio::abm::TransportMode mode)
     364             :     {
     365         351 :         m_last_transport_mode = mode;
     366         351 :     }
     367             : 
     368             :     /**
     369             :      * @brief Get this persons RandomNumberGenerator counter.
     370             :      * @see mio::abm::PersonalRandomNumberGenerator.
     371             :      */
     372        6642 :     Counter<uint32_t>& get_rng_counter()
     373             :     {
     374        6642 :         return m_rng_counter;
     375             :     }
     376             : 
     377             :     /**
     378             :      * @brief Get the latest #ProtectionType and its initial TimePoint of the Person.
     379             :      */
     380             :     ProtectionEvent get_latest_protection() const;
     381             : 
     382             :     /// This method is used by the default serialization feature.
     383          18 :     auto default_serialize()
     384             :     {
     385          36 :         return Members("Person")
     386          54 :             .add("location", m_location)
     387          54 :             .add("location_type", m_location_type)
     388          54 :             .add("assigned_locations", m_assigned_locations)
     389          54 :             .add("vaccinations", m_vaccinations)
     390          54 :             .add("infections", m_infections)
     391          54 :             .add("home_isolation_start", m_home_isolation_start)
     392          54 :             .add("age_group", m_age)
     393          54 :             .add("time_at_location", m_time_at_location)
     394          54 :             .add("rnd_workgroup", m_random_workgroup)
     395          54 :             .add("rnd_schoolgroup", m_random_schoolgroup)
     396          54 :             .add("rnd_go_to_work_hour", m_random_goto_work_hour)
     397          54 :             .add("rnd_go_to_school_hour", m_random_goto_school_hour)
     398          54 :             .add("mask", m_mask)
     399          54 :             .add("compliance", m_compliance)
     400          54 :             .add("id", m_person_id)
     401          54 :             .add("cells", m_cells)
     402          54 :             .add("last_transport_mode", m_last_transport_mode)
     403          54 :             .add("rng_counter", m_rng_counter)
     404          54 :             .add("test_results", m_test_results);
     405             :     }
     406             : 
     407             :     /**
     408             :      * @brief Add TestResult to the Person
     409             :      * @param[in] t The TimePoint of the test.
     410             :      * @param[in] type The TestType of the test.
     411             :      * @param[in] result The result of the test.
     412             :     */
     413             :     void add_test_result(TimePoint t, TestType type, bool result);
     414             : 
     415             :     /**
     416             :      * @brief Get the most recent TestResult performed from the Person based on the TestType.
     417             :      * If time_of_testing == TimePoint(std::numeric_limits<int>::min()), there is no previous TestResult.
     418             :      * @param[in] type The TestType of the test.
     419             :      * @return The latest TestResult of the given Type.
     420             :     */
     421             :     TestResult get_test_result(TestType type) const;
     422             : 
     423             : private:
     424             :     LocationId m_location; ///< Current Location of the Person.
     425             :     LocationType m_location_type; ///< Type of the current Location.
     426             :     std::vector<LocationId> m_assigned_locations; /**! Vector with the indices of the assigned Locations so that the
     427             :     Person always visits the same Home or School etc. */
     428             :     std::vector<ProtectionEvent> m_vaccinations; ///< Vector with all vaccinations the Person has received.
     429             :     std::vector<Infection> m_infections; ///< Vector with all Infection%s the Person had.
     430             :     TimePoint m_home_isolation_start; ///< TimePoint when the Person started isolation at home.
     431             :     AgeGroup m_age; ///< AgeGroup the Person belongs to.
     432             :     TimeSpan m_time_at_location; ///< Time the Person has spent at its current Location so far.
     433             :     double m_random_workgroup; ///< Value to determine if the Person goes to work or works from home during lockdown.
     434             :     double m_random_schoolgroup; ///< Value to determine if the Person goes to school or stays at home during lockdown.
     435             :     double m_random_goto_work_hour; ///< Value to determine at what time the Person goes to work.
     436             :     double m_random_goto_school_hour; ///< Value to determine at what time the Person goes to school.
     437             :     Mask m_mask; ///< The Mask of the Person.
     438             :     std::vector<ScalarType>
     439             :         m_compliance; ///< Vector of compliance values for all #InterventionType%s. Values from 0 to 1.
     440             :     PersonId m_person_id; ///< Id of the Person.
     441             :     std::vector<uint32_t> m_cells; ///< Vector with all Cell%s the Person visits at its current Location.
     442             :     mio::abm::TransportMode m_last_transport_mode; ///< TransportMode the Person used to get to its current Location.
     443             :     Counter<uint32_t> m_rng_counter{0}; ///< counter for RandomNumberGenerator.
     444             :     CustomIndexArray<TestResult, TestType> m_test_results; ///< CustomIndexArray for TestResults.
     445             : };
     446             : 
     447             : } // namespace abm
     448             : 
     449             : /// @brief Creates an instance of abm::Person for default serialization.
     450             : template <>
     451             : struct DefaultFactory<abm::Person> {
     452           9 :     static abm::Person create()
     453             :     {
     454             :         return abm::Person(thread_local_rng(), abm::LocationType::Count, abm::LocationId(), AgeGroup(0),
     455           9 :                            abm::PersonId());
     456             :     }
     457             : };
     458             : 
     459             : } // namespace mio
     460             : 
     461             : #endif

Generated by: LCOV version 1.14