1
- use anyhow:: { ensure , Context } ;
1
+ use anyhow:: Context ;
2
2
use clap:: { ArgAction , Parser , ValueEnum } ;
3
3
use ecdna_evo:: {
4
4
distribution:: EcDNADistribution ,
5
5
segregation:: {
6
6
Binomial , BinomialNoNminus , BinomialNoUneven , Deterministic , Segregate ,
7
7
} ,
8
- Snapshot ,
8
+ SnapshotCells ,
9
9
} ;
10
10
use rand:: Rng ;
11
11
use sosa:: { IterTime , NbIndividuals , Options } ;
@@ -89,112 +89,45 @@ pub struct Cli {
89
89
#[ arg( short, long, default_value_t = 12 , conflicts_with = "debug" ) ]
90
90
/// Number of independent realisations to simulate of the same stochastic process
91
91
runs : usize ,
92
- #[ arg( long, requires = "subsamples" , value_delimiter = ',' , require_equals = true , num_args = 0 ..) ]
93
- /// Snapshots to take to save the simulation, requires `subsamples`.
94
- ///
95
- /// The combination of `snapshots` with `subsamples` gives four different
96
- /// behaviours:
97
- ///
98
- /// 1. when `snapshots.len() = 1` and `subsamples.len() = 1`: subsample once with the number of cells corresponding to `snapshots[0]`
99
- ///
100
- /// 2. when `snapshots.len() > 1` and `subsamples.len() = 1`: for every `s` in `snapshots`, subsample with the number of cells corresponding to `snapshots[0]`
101
- ///
102
- /// 3. when `snapshots.len() = 1` and `subsamples.len() > 1`: for every `c` in `subsamples`, subsample once with the number of cells corresponding to `c`
103
- ///
104
- /// 4. when `snapshots.len() > 1` and `subsamples.len() > 1`: for every pair `(s, c)` in `snapshots.zip(subsamples)`, subsample at time `s` with `c` cells
105
- snapshots : Option < Vec < f32 > > ,
106
- /// Number of cells to subsample before saving the measurements, leave
107
- /// empty when no subsample is needed.
108
- /// If subsampling is performed, the measurements of the whole population
109
- /// will also be saved.
110
- ///
111
- /// See help for `snapshots` for more details.
112
- #[ arg( long, requires = "snapshots" , num_args = 0 .., value_delimiter = ',' , require_equals = true ) ]
113
- subsamples : Option < Vec < usize > > ,
92
+ #[ arg( long, value_delimiter = ',' , require_equals = true , num_args = 0 ..) ]
93
+ /// Number of cells that will trigger the saving of the ecDNA distribution.
94
+ snapshots : Option < Vec < usize > > ,
114
95
#[ arg( short, long, action = clap:: ArgAction :: Count , conflicts_with = "debug" , default_value_t = 0 ) ]
115
96
verbosity : u8 ,
116
97
}
117
98
118
99
fn build_snapshots (
119
- years : u64 ,
120
100
cells : NbIndividuals ,
121
- subsamples : Option < Vec < usize > > ,
122
- snapshots : Option < Vec < f32 > > ,
123
- ) -> anyhow:: Result < VecDeque < Snapshot > > {
124
- let mut snapshots = match ( subsamples, snapshots) {
125
- ( Some ( sub) , Some ( snap) ) => {
126
- match ( & sub[ ..] , & snap[ ..] ) {
127
- // subsample `unique_sub` once at `unique_snap` time
128
- ( [ unique_sub] , [ unique_snap] ) => VecDeque :: from_iter (
129
- [ ( unique_sub, unique_snap) ] . into_iter ( ) . map (
130
- |( & cells2sample, & time) | Snapshot {
131
- cells2sample,
132
- time,
133
- } ,
134
- ) ,
135
- ) ,
136
- // subsample `unique_sub` at several `snaps` times
137
- ( [ unique_sub] , snaps) => VecDeque :: from_iter (
138
- snaps. iter ( ) . zip ( std:: iter:: repeat ( unique_sub) ) . map (
139
- |( & time, & cells2sample) | Snapshot {
140
- cells2sample,
141
- time,
142
- } ,
143
- ) ,
144
- ) ,
145
- // subsample with different cells `unique_sub` once at `unique_snap` time
146
- ( subs, [ unique_snap] ) => VecDeque :: from_iter (
147
- subs. iter ( ) . zip ( std:: iter:: repeat ( unique_snap) ) . map (
148
- |( & cells2sample, & time) | Snapshot {
149
- cells2sample,
150
- time,
151
- } ,
152
- ) ,
153
- ) ,
154
- // subsample with many cells `subs` at specific `snaps`
155
- ( subs, snaps) => {
156
- ensure ! (
157
- subs. len( ) == snaps. len( ) ,
158
- "the lenght of snapshots do not match the lenght of subsamples"
159
- ) ;
160
- VecDeque :: from_iter ( subs. iter ( ) . zip ( snaps) . map (
161
- |( & cells2sample, & time) | Snapshot {
162
- cells2sample,
163
- time,
164
- } ,
165
- ) )
166
- }
167
- }
168
- }
169
- ( None , None ) => VecDeque :: from_iter (
170
- build_snapshots_from_time (
171
- 10usize ,
172
- if years > 1 { years as f32 - 1. } else { 0.9 } ,
173
- )
174
- . into_iter ( )
175
- . map ( |t| Snapshot { cells2sample : cells as usize , time : t } ) ,
101
+ snapshots : Option < Vec < usize > > ,
102
+ ) -> anyhow:: Result < VecDeque < SnapshotCells > > {
103
+ let mut snapshots = match snapshots {
104
+ Some ( s) => VecDeque :: from_iter (
105
+ s. into_iter ( ) . map ( |cells| SnapshotCells { cells } ) ,
176
106
) ,
177
- _ => unreachable ! ( ) ,
107
+ None => VecDeque :: from ( build_snapshots_from_cells ( 11 , cells as usize ) ) ,
178
108
} ;
179
109
180
110
snapshots. make_contiguous ( ) ;
181
111
snapshots
182
112
. as_mut_slices ( )
183
113
. 0
184
- . sort_by ( |s1, s2| s1. time . partial_cmp ( & s2. time ) . unwrap ( ) ) ;
114
+ . sort_by ( |s1, s2| s1. cells . partial_cmp ( & s2. cells ) . unwrap ( ) ) ;
185
115
Ok ( snapshots)
186
116
}
187
117
188
- fn build_snapshots_from_time ( n_snapshots : usize , time : f32 ) -> Vec < f32 > {
189
- let dx = time / ( ( n_snapshots - 1 ) as f32 ) ;
190
- let mut x = vec ! [ 0. ; n_snapshots] ;
118
+ fn build_snapshots_from_cells (
119
+ n_snapshots : usize ,
120
+ cells : usize ,
121
+ ) -> Vec < SnapshotCells > {
122
+ let dx = cells / ( n_snapshots - 1 ) ;
123
+ let mut x = vec ! [ 1 ; n_snapshots] ;
191
124
for i in 1 ..n_snapshots - 1 {
192
125
x[ i] = x[ i - 1 ] + dx;
193
126
}
194
127
195
128
x. shrink_to_fit ( ) ;
196
- x[ n_snapshots - 1 ] = time ;
197
- x
129
+ x[ n_snapshots - 1 ] = cells ;
130
+ x. into_iter ( ) . map ( |v| SnapshotCells { cells : v } ) . collect ( )
198
131
}
199
132
200
133
impl Cli {
@@ -220,14 +153,7 @@ impl Cli {
220
153
}
221
154
} ;
222
155
223
- let snapshots =
224
- build_snapshots ( years, cells, cli. subsamples , cli. snapshots )
225
- . unwrap ( ) ;
226
- ensure ! (
227
- snapshots. iter( ) . all( |s| s. time < years as f32 ) ,
228
- "times to take `snapshots` must be smaller than total `years`"
229
- ) ;
230
-
156
+ let snapshots = build_snapshots ( cells, cli. snapshots ) . unwrap ( ) ;
231
157
let segregation = cli. segregation . into ( ) ;
232
158
233
159
// if both d0, d1 are either unset or equal to 0, pure birth,
0 commit comments