@@ -83,17 +83,17 @@ abstract type AbstractModel end
8383Base. parent (m:: AbstractModel ) = getfield (m, :parent )
8484setparent (m:: AbstractModel , newparent) = @set m. parent = newparent
8585
86- params (m:: AbstractModel ) = params (parent (m))
87- stripparams (m:: AbstractModel ) = stripparams (parent (m))
86+ params (m:: AbstractModel ; kw... ) = params (parent (m); kw... )
87+ stripparams (m:: AbstractModel ; kw... ) = stripparams (parent (m); kw... )
88+ paramfieldnames (m:: AbstractModel ; kw... ) = paramfieldnames (parent (m); kw... )
89+ paramparenttypes (m:: AbstractModel ; kw... ) = paramparenttypes (parent (m); kw... )
8890function update (x:: T , values) where {T<: AbstractModel }
8991 hasfield (T, :parent ) || _updatenotdefined (T)
9092 setparent (x, update (parent (x), values))
9193end
9294
9395@noinline _update_methoderror (T) = error (" Interface method `update` is not defined for $T " )
9496
95- paramfieldnames (m) = Flatten. fieldnameflatten (parent (m), SELECT, IGNORE)
96- paramparenttypes (m) = Flatten. metaflatten (parent (m), _fieldparentbasetype, SELECT, IGNORE)
9797
9898_fieldparentbasetype (T, :: Type{Val{N}} ) where N = T. name. wrapper
9999
@@ -102,64 +102,64 @@ _fieldparentbasetype(T, ::Type{Val{N}}) where N = T.name.wrapper
102102
103103# It may seem expensive always calling `param`, but flattening the
104104# object occurs once at compile-time, and should have very little cost here.
105- Base. length (m:: AbstractModel ) = length (params (m))
106- Base. size (m:: AbstractModel ) = (length (params (m)),)
107- Base. first (m:: AbstractModel ) = first (params (m))
108- Base. last (m:: AbstractModel ) = last (params (m))
105+ Base. length (m:: AbstractModel ; kw ... ) = length (params (m; kw ... ))
106+ Base. size (m:: AbstractModel ; kw ... ) = (length (params (m; kw ... )),)
107+ Base. first (m:: AbstractModel ; kw ... ) = first (params (m; kw ... ))
108+ Base. last (m:: AbstractModel ; kw ... ) = last (params (m; kw ... ))
109109Base. firstindex (m:: AbstractModel ) = 1
110- Base. lastindex (m:: AbstractModel ) = length (params (m))
110+ Base. lastindex (m:: AbstractModel ; kw ... ) = length (params (m; kw ... ))
111111Base. getindex (m:: AbstractModel , i) = getindex (params (m), i)
112112Base. iterate (m:: AbstractModel ) = (first (params (m)), 1 )
113113Base. iterate (m:: AbstractModel , s) = s > length (m) ? nothing : (params (m)[s], s + 1 )
114114
115115# Vector methods
116- Base. collect (m:: AbstractModel ) = collect (m. val)
117- Base. vec (m:: AbstractModel ) = collect (m)
118- Base. Array (m:: AbstractModel ) = vec (m)
116+ Base. collect (m:: AbstractModel ; kw ... ) = collect (m[ : val; kw ... ] )
117+ Base. vec (m:: AbstractModel ; kw ... ) = collect (m; kw ... )
118+ Base. Array (m:: AbstractModel ; kw ... ) = vec (m; kw ... )
119119
120120# Dict methods - data as columns
121121Base. haskey (m:: AbstractModel , key:: Symbol ) = key in keys (m)
122122Base. keys (m:: AbstractModel ) = _keys (params (m), m)
123123
124- @inline function Base. setindex! (m:: AbstractModel , x, nm:: Symbol )
124+ @inline function Base. setindex! (m:: AbstractModel , x, nm:: Symbol ; kw ... )
125125 if nm == :component
126126 erorr (" cannot set :component index" )
127127 elseif nm == :fieldname
128128 erorr (" cannot set :fieldname index" )
129129 else
130130 newparent = if nm in keys (m)
131- _setindex (parent (m), Tuple (x), nm)
131+ _setindex (parent (m), Tuple (x), nm; kw ... )
132132 else
133- _addindex (parent (m), Tuple (x), nm)
133+ _addindex (parent (m), Tuple (x), nm; kw ... )
134134 end
135135 setparent! (m, newparent)
136136 end
137137end
138138# TODO do this with lenses
139- @inline function _setindex (obj, xs:: Tuple , nm:: Symbol )
139+ @inline function _setindex (obj, xs:: Tuple , nm:: Symbol ; select = SELECT, ignore = IGNORE )
140140 lens = Setfield. PropertyLens {nm} ()
141- newparams = map (params (obj), xs) do par , x
142- Param ( Setfield. set (parent (par ), lens, x))
141+ newparams = map (params (obj; select, ignore ), xs) do p , x
142+ setparent (p, Setfield. set (parent (p ), lens, x))
143143 end
144- Flatten. reconstruct (obj, newparams, SELECT, IGNORE )
144+ Flatten. reconstruct (obj, newparams, select, ignore )
145145end
146- @inline function _addindex (obj, xs:: Tuple , nm:: Symbol )
147- newparams = map (params (obj), xs) do par , x
148- Param ( (; parent (par )... , (nm => x,). .. ))
146+ @inline function _addindex (obj, xs:: Tuple , nm:: Symbol ; select = SELECT, ignore = IGNORE )
147+ newparams = map (params (obj), xs) do p , x
148+ setparent (p, (; parent (p )... , (nm => x,). .. ))
149149 end
150- Flatten. reconstruct (obj, newparams, SELECT, IGNORE )
150+ Flatten. reconstruct (obj, newparams, select, ignore )
151151end
152152
153153_keys (params:: Tuple , m:: AbstractModel ) = (:component , :fieldname , keys (first (params))... )
154154_keys (params:: Tuple{} , m:: AbstractModel ) = ()
155155
156- @inline function Base. getindex (m:: AbstractModel , nm:: Symbol )
156+ @inline function Base. getindex (m:: AbstractModel , nm:: Symbol ; kw ... )
157157 if nm == :component
158- paramparenttypes (m)
158+ paramparenttypes (m; kw ... )
159159 elseif nm == :fieldname
160- paramfieldnames (m)
160+ paramfieldnames (m; kw ... )
161161 else
162- map (p -> getindex (p, nm), params (m))
162+ map (p -> getindex (p, nm), params (m; kw ... ))
163163 end
164164end
165165
@@ -181,16 +181,15 @@ end
181181
182182setparent! (m:: AbstractModel , newparent) = setfield! (m, :parent , newparent)
183183
184- update! (m:: AbstractModel , vals:: AbstractVector{<:AbstractParam} ) = update! (m, Tuple (vals))
185- function update! (params:: Tuple{<:AbstractParam,Vararg{<:AbstractParam}} )
186- setparent! (m, Flatten. reconstruct (parent (m), params, SELECT, IGNORE))
184+ function update! (m:: AbstractModel , vals:: AbstractVector{<:AbstractParam} ; kw... )
185+ update! (m, Tuple (vals); kw... )
187186end
188- function update! (m:: AbstractModel , table)
187+ function update! (m:: AbstractModel , table; kw ... )
189188 cols = (c for c in Tables. columnnames (table) if ! (c in (:component , :fieldname )))
190189 for col in cols
191- setindex! (m, Tables. getcolumn (table, col), col)
190+ setindex! (m, Tables. getcolumn (table, col), col; kw ... )
192191 end
193- m
192+ return m
194193end
195194
196195"""
@@ -220,30 +219,34 @@ mutable struct Model <: AbstractModel
220219end
221220Model (m:: AbstractModel ) = Model (parent (m))
222221
223- @inline @generated function _update_params (ps:: P , values:: Union{<:AbstractVector,<:Tuple} ) where {N,P<: NTuple{N,Param} }
222+ const ParamTuple = Tuple{Vararg{<: AbstractParam }}
223+
224+ @inline @generated function _update_params (ps:: P , values:: Union{<:AbstractVector,<:Tuple} ) where {P<: ParamTuple }
224225 expr = Expr (:tuple )
225- for i in 1 : N
226- expr_i = :(Param ( NamedTuple {keys(ps[$i])} ((values[$ i], Base . tail (parent (ps[$ i]))... ))))
226+ for i in 1 : length (ps . parameters)
227+ expr_i = :(setparent (ps[ $ i], NamedTuple {keys(ps[$i])} ((values[$ i], tail (parent (ps[$ i]))... ))))
227228 push! (expr. args, expr_i)
228229 end
229230 return expr
230231end
231232
232- update (x, values) = _update (ModelParameters. params (x), x, values)
233- @inline function _update (p:: P , x, values:: Union{<:AbstractVector,<:Tuple} ) where {N,P<: NTuple{N,Param} }
234- @assert length (values) == N " values length must match the number of parameters"
235- newparams = _update_params (p, values)
236- Flatten. reconstruct (x, newparams, SELECT, IGNORE)
233+ update (x, values; kw... ) = _update (ModelParameters. params (x), x, values; kw... )
234+ @inline function _update (ps:: P , x, values:: Union{<:AbstractVector,<:Tuple} ;
235+ select= SELECT, ignore= IGNORE
236+ ) where {P<: ParamTuple }
237+ @assert length (values) == length (ps) " values length must match the number of parameters"
238+ newparams = _update_params (ps, values)
239+ return Flatten. reconstruct (x, newparams, select, ignore)
237240end
238- @inline function _update (p :: P , x, table) where {N, P<: NTuple{N,Param} }
239- @assert size (table, 1 ) == N " number of rows must match the number of parameters"
241+ @inline function _update (ps :: P , x, table; select = SELECT, ignore = IGNORE ) where {P<: ParamTuple }
242+ @assert size (table, 1 ) == length (ps) " number of rows must match the number of parameters"
240243 colnames = (c for c in Tables. columnnames (table) if ! (c in (:component , :fieldname )))
241- newparams = map (p , tuple (1 : N ... )) do param , i
242- let names = keys (param );
243- Param ( NamedTuple {names} (map (name -> Tables. getcolumn (table, name)[i], names)))
244+ newparams = map (ps , tuple (1 : length (ps) ... )) do p , i
245+ let names = keys (p );
246+ setparent (p, NamedTuple {names} (map (name -> Tables. getcolumn (table, name)[i], names)))
244247 end
245248 end
246- Flatten. reconstruct (x, newparams, SELECT, IGNORE )
249+ return Flatten. reconstruct (x, newparams, select, ignore )
247250end
248251
249252"""
@@ -270,17 +273,17 @@ StaticModel(m::AbstractModel) = StaticModel(parent(m))
270273
271274# Model Utils
272275
273- _expandpars (x) = Flatten. reconstruct (parent, _expandkeys (parent), SELECT, IGNORE )
276+ _expandpars (x) = Flatten. reconstruct (parent, _expandkeys (parent), select, ignore )
274277# Expand all Params to have the same keys, filling with `nothing`
275278# This probably will allocate due to `union` returning `Vector`
276279function _expandkeys (x)
277280 pars = params (x)
278281 allkeys = Tuple (union (map (keys, pars)... ))
279- return map (pars) do par
282+ return map (pars) do p
280283 vals = map (allkeys) do key
281- get (par , key, nothing )
284+ get (p , key, nothing )
282285 end
283- Param ( NamedTuple {allkeys} (vals))
286+ setparent (p, NamedTuple {allkeys} (vals))
284287 end
285288end
286289
0 commit comments