@@ -80,15 +80,65 @@ def __init__(
8080 exposure : Exposures ,
8181 hazard : Hazard ,
8282 impfset : ImpactFuncSet ,
83+ measure : Measure | None ,
8384 date : int | datetime .date | str ,
8485 ref_only : bool = False ,
8586 ) -> None :
8687 self ._exposure = exposure if ref_only else copy .deepcopy (exposure )
8788 self ._hazard = hazard if ref_only else copy .deepcopy (hazard )
8889 self ._impfset = impfset if ref_only else copy .deepcopy (impfset )
89- self ._measure = None
90+ self ._measure = measure if ref_only else copy . deepcopy ( impfset )
9091 self ._date = self ._convert_to_date (date )
9192
93+ @classmethod
94+ def from_triplet (
95+ cls ,
96+ * ,
97+ exposure : Exposures ,
98+ hazard : Hazard ,
99+ impfset : ImpactFuncSet ,
100+ date : int | datetime .date | str ,
101+ ref_only : bool = False ,
102+ ) -> "Snapshot" :
103+ """Create a Snapshot from exposure, hazard and impact functions set
104+
105+ This method is the main point of entry for the creation of Snapshot. It
106+ creates a new Snapshot object for the given date with copies of the
107+ hazard, exposure and impact function set given in argument (or
108+ references if ref_only is True)
109+
110+ Parameters
111+ ----------
112+ exposure : Exposures
113+ hazard : Hazard
114+ impfset : ImpactFuncSet
115+ date : int | datetime.date | str
116+ ref_only : bool
117+ If true, uses references to the exposure, hazard and impact
118+ function objects. Note that modifying the original objects after
119+ computations using the Snapshot might lead to inconsistencies in
120+ results.
121+
122+ Returns
123+ -------
124+ Snapshot
125+
126+ Notes
127+ -----
128+
129+ To create a Snapshot with a measure, first create the Snapshot without
130+ the measure using this method, and use `apply_measure(measure)` afterward.
131+
132+ """
133+ return cls (
134+ exposure = exposure ,
135+ hazard = hazard ,
136+ impfset = impfset ,
137+ measure = None ,
138+ date = date ,
139+ ref_only = ref_only ,
140+ )
141+
92142 @property
93143 def exposure (self ) -> Exposures :
94144 """Exposure data for the snapshot."""
@@ -129,17 +179,17 @@ def _convert_to_date(date_arg) -> datetime.date:
129179 if isinstance (date_arg , int ):
130180 # Assume the integer represents a year
131181 return datetime .date (date_arg , 1 , 1 )
132- elif isinstance (date_arg , str ):
182+ if isinstance (date_arg , str ):
133183 # Try to parse the string as a date
134184 try :
135185 return datetime .datetime .strptime (date_arg , "%Y-%m-%d" ).date ()
136- except ValueError :
137- raise ValueError ("String must be in the format 'YYYY-MM-DD'" )
138- elif isinstance (date_arg , datetime .date ):
186+ except ValueError as exc :
187+ raise ValueError ("String must be in the format 'YYYY-MM-DD'" ) from exc
188+ if isinstance (date_arg , datetime .date ):
139189 # Already a date object
140190 return date_arg
141- else :
142- raise TypeError ("date_arg must be an int, str, or datetime.date" )
191+
192+ raise TypeError ("date_arg must be an int, str, or datetime.date" )
143193
144194 def apply_measure (self , measure : Measure ) -> "Snapshot" :
145195 """Create a new snapshot by applying a Measure object.
@@ -158,8 +208,9 @@ def apply_measure(self, measure: Measure) -> "Snapshot":
158208
159209 """
160210
161- LOGGER .debug (f "Applying measure { measure . name } on snapshot { id (self )} " )
211+ LOGGER .debug ("Applying measure %s on snapshot %s" , measure . name , id (self ))
162212 exp , impfset , haz = measure .apply (self .exposure , self .impfset , self .hazard )
163- snap = Snapshot (exposure = exp , hazard = haz , impfset = impfset , date = self .date )
164- snap ._measure = measure
213+ snap = Snapshot (
214+ exposure = exp , hazard = haz , impfset = impfset , date = self .date , measure = measure
215+ )
165216 return snap
0 commit comments