lightmotif-py 0.10.1

PyO3 bindings and Python interface to the lightmotif crate.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).


## [Unreleased]
[Unreleased]: https://github.com/althonos/lightmotif/compare/v0.10.1...HEAD


## [v0.10.1] - 2026-03-25
[v0.10.1]: https://github.com/althonos/lightmotif/compare/v0.10.0...v0.10.1

### Added

#### `lightmotif`
- Lossy constructor for `EncodedSequence` replacing unknown characters with `Alphabet::default_symbol`.
- `block_size` option to change the number of rows of the block used in a `Scanner`.

### Fixed

#### `lightmotif`
- `ScoringMatrix::to_discrete` failing conversion on cells with `-inf` scores (due to zero pseudocounts).
- Panic in `Scanner::next` caused by empty scores buffer.
- Non-saturating add being used in `score_u8_neon` causing `Scanner` to ignore some hits on Arm platforms.

### Changed

#### `lightmotif`
- Update `rand` dependency to `v0.10.0`.

##### `lightmotif-py`
- Update `pyo3` dependency to `v0.28.0.`.


## [v0.10.0] - 2025-05-19
[v0.10.0]: https://github.com/althonos/lightmotif/compare/v0.9.1...v0.10.0

### Added

#### `lightmotif`
- Experimental Gibbs sampler implementation for motif detection in `zoops` and `oops` modes.
- `IndexMut<MatrixCoordinates>` trait implementation for `DenseMatrix` type.
- `AsRef<Vec<T>>` for `Scores<T>`.
- `information_content` methods to `WeightMatrix` and `ScoringMatrix`.
- `consensus` method to `CountMatrix`.
- `FrequencyMatrix::into_scoring` to take ownership of a frequency matrix and converting it inplace into a `ScoringMatrix`.
- Implement `size_hint` for `StripedScores` iterator.
- Cumulative distribution approximation for `ScoringMatrix`.
- Add `ScoringMatrix::to_score_distribution` method to compute a score distribution suitable for P-value estimation.
- Trait to compute correlations for `lightmotif::pwm` matrices.
- `new_unchecked` constructors to `lightmotif::pwm` types (undocumented).
- Efficient look-up table implementation for Aarch64 NEON `f32`-scoring.

#### `lightmotif-io`
- Reader for MEME format files.

### Changed

#### `lightmotif`
- Implement `DenseMatrix` iterators without unsafe code.
- Make `lightmotif::scan::Hit` fields read-only.
- Inline short functions in `lightmotif` core moduels.
- Make the `ravel` methods of `DenseMatrix` unsafe.
- Allow accessing and configuring the row capacity of a `DenseMatrix`.
- Always pre-allocate additional rows when creating a new `StripedSequence` to avoid reallocation for wrap rows.
- Use pointers to avoid matrix indexing inside pipeline hot loops.
- Skip use of NEON for `Score<Protein>` since generic code is faster.

#### `lightmotif-io`
- Update `nom` dependency to `8.0`.

#### `lightmotif-py`
- Update `pyo3` dependency to `0.23`.
- Use `maturin` instead of `setuptools-rust` to build Python bindings from source.

### Fixed

#### `lightmotif`
- Use all columns of the matrix in `CountMatrix::entropy`.
- Fix missing `_mm_sfence` in `score_f32_avx2_permute` code.
- Avoid multiple `log` calls in `FrequencyMatrix::to_scoring`.

### Removed

#### `lightmotif`
- Const method declaration for matrix traits not `const` in `lightmotif::pwm`.


## [v0.9.1] - 2024-09-03
[v0.9.1]: https://github.com/althonos/lightmotif/compare/v0.9.0...v0.9.1

### Added

#### `lightmotif-py`
- Arch User Repository package `python-lightmotif` to distribute the Python package on ArchLinux.

### Fixed

#### `lightmotif-py`
- Fix issues with source distribution missing required files for compilation.
- Remove unused test data to reduce size of source distribution.


## [v0.9.0] - 2024-09-02
[v0.9.0]: https://github.com/althonos/lightmotif/compare/v0.8.0...v0.9.0

### Added

#### `lightmotif`
- `DenseMatrix::ravel` to get the array of a `DenseMatrix` as a single continuous slice.

#### `lightmotif-py`
- Support for protein alphabets ([#5]https://github.com/althonos/lightmotif/issues/5).
- `protein` property to `CountMatrix`, `WeightMatrix`, `ScoringMatrix`, `EncodedSequence` and `StripedSequence`.
- `Scanner` class to use the new DNA scanning algorithm.
- Buffer protocol implmementation for `ScoringMatrix` objects.
- `lightmotif.load` function to load one or more `Motif` from a file-like object ([#6]https://github.com/althonos/lightmotif/issues/6).
- `Motif.name` property to store the optional name of a `Motif`.
- Several `Motif` subclasses to store motif and metadata loaded from a file.
- Type annotations for the `lightmotif.lib` package.

### Fixed

#### `lightmotif-io`
- Parsing of floating-point numbers in JASPAR parser.
- Panic on error unwrapping in `lightmotif-io`.

### Changed

#### `lightmotif`
- Rewrite `DenseMatrix` with constant platform-specific alignment to reduce amount of `unsafe` code.

### Removed

#### `lightmotif-py`
- `alphabet` parameter of `ScoringMatrix` and `EncodedSequence`.


## [v0.8.0] - 2024-06-28
[v0.8.0]: https://github.com/althonos/lightmotif/compare/v0.7.3...v0.8.0

### Added

#### `lightmotif`
- `lightmotif::pwm::DiscreteMatrix` to store a discretized `ScoringMatrix`.
- `MatrixElement` marker trait for `Default + Copy` types that can be used as a `DenseMatrix` element.
- `lightmotif::scores::Scores` wrapper of `Vec<T>` with shortcut `max`, `threshold` and `argmax` methods.
- AVX2 and NEON implementations of `Score<u8, Dna>` pipeline operation.

### Fixed

#### `lightmotif`
- Remove requirement for `T: Debug` in `Clone` implementation of `DenseMatrix<T>`.
- SSE2 and AVX2 implementations of `Argmax` not returning the last index in case of ties.

#### `lightmotif-tfmpvalue`
- Cache internal buffer for Q-values to avoid reallocation between iterations.

### Changed

#### `lightmotif`
- Cache the `Pipeline` used in `lightmotif::scan::Scanner`.
- Make `lightmotif::scores::StripedScores` generic over the score type.
- Make `Maximum` and `Threshold` generic over the score type.
- Use a discrete matrix in `Scanner` to quickly eliminate blocks without candidate position above given threshold.
- Compile crate without the `rand` and `rand-distr` features by default.

#### `lightmotif-py`
- Update `pyo3` dependency to `v0.22.0`.


## [v0.7.3] - 2024-06-17
[v0.7.3]: https://github.com/althonos/lightmotif/compare/v0.7.2...v0.7.3

### Added

#### `lightmotif-io`
- `lightmotif_io::jaspar` to read matrices in raw JASPAR format.
- Implementation of `Clone` and `Error` for the `lightmotif_io::error::Error` type.

### Changed

#### `lightmotif`
- Use logarithmic subtraction in `FrequencyMatrix::to_scoring`.
- Use `_mm256_permutevara8x32_ps` instead of `_mm256_permutevar_ps` in AVX2 implementation to avoid special handling of unknown matric character `N`.

### Fixed

#### `lightmotif`
- Striping of empty sequences panicking on AVX2 implementation.
- Scoring of empty range of rows panicking.
- Invalid alignment of data in AVX2 code.
- `Clone` implementation of `DenseMatrix` not preserving memory alignment.


## [v0.7.2] - 2024-06-14
[v0.7.2]: https://github.com/althonos/lightmotif/compare/v0.7.1...v0.7.2

### Added

#### `lightmotif-py`
- Add `__len__` implementation for all matrix clases.
- Allow changing the logarithm base in `WeightMatrix.log_odds` method.
- Implement `__getitem__` for row access for all matrix classes.


## [v0.7.1] - 2024-06-14
[v0.7.1]: https://github.com/althonos/lightmotif/compare/v0.7.0...v0.7.1

### Fixed

#### `lightmotif`
- Resizing of `StripedScores` output in NEON implementation of `Score`.


## [v0.7.0] - 2024-06-14
[v0.7.0]: https://github.com/althonos/lightmotif/compare/v0.6.0...v0.7.0

### Added

#### `lightmotif`
- Implement indexing of `StripedSequence` by sequence index.
- `matrix` accessor to all matrix types in `lightmotif::pwm` and `lightmotif::seq`.
- `entropy` and `information_content` methods to `CountMatrix`.
- `SymbolCount` trait for counting the number of occurrences of a symbol in an iterable.
- Several `Background` constructors for counting occurences in one or more sequences.
- `FromIterator<A::Symbol>` constructor for `EncodedSequence<A>`.
- `MultipleOf<N>` trait to simplify typenums in platform code signatures.
- Sampling of random sequences using the `rand` dependency under a feature flag.
- `ScoringMatrix.score_into` method to re-use a `StripedScores` buffer.
- `ScoringMatrix.score_position` method to score a single sequence position.
- Indexing by `MatrixCoordinates` in `DenseMatrix`.
- Support for chanding logarithm base when building a `ScoringMatrix` from a `WeightMatrix`.
- Scanning algorithm for finding hits in a sequence with an iterator without allocating `StripedScores` for each sequence position.

### `lightmotif-py`
- Support for optional TFMPvalue interface in Python bindings under GPLv3+ code.
- Constructor for `ScoringMatrix` class.
- `ScoringMatrix.reverse_complement` to compute the reverse-complement of a scoring matrix.

### Changed

#### `lightmotif`
- Make `EncodedSequence.stripe` use a dispatching `Pipeline` internally.
- Require power-of-two alignment in `DenseMatrix` implementations.
- Update `generic-array` dependency to `v1.0`.
- Change order of parameters in `ScoringMatrix.score`.
- Reorganize scoring trait and implement row-slice scoring for AVX2 and SSE2.
- Rewrite `Pipeline::threshold` to return matrix coordinates instead of a sequence index.
- Rewrite `Pipeline::argmax` to return matrix coordinates instead of a sequence index.

#### `lightmotif-py`
- Streamline the use of pipelined functions in Python bindings.

### Fixed

#### `lightmotif`
- Handling of unknown residues in `permute` implementation of `Score` on AVX2.
- `PartialEq` for `DenseMatrix` to ignore alignment padding in each row. 

### Removed

#### `lightmotif`
- Platform-specific code for thresholding a `StripedScores` matrix.
- Direct attribute access in `StripedSequence`.

#### `lightmotif-transfac`
- Remove crate from repository, superseded by the `lightmotif-io` crate.


## [v0.6.0] - 2023-12-13
[v0.6.0]: https://github.com/althonos/lightmotif/compare/v0.5.1...v0.6.0

### Added

#### `lightmotif`
- Validating constructor `::pwm::FrequencyMatrix::new` testing for frequencies on each ranks.
- Getter to the raw data matrix of a `::pwm::FrequencyMatrix`.

#### `lightmotif-io`
New crate with JASPAR, TRANSFAC and UNIPROBE format parsers.

### Changed

#### `lightmotif`
- Make `max_score` and `min_score` columns of `::pwm::ScoringMatrix` ignore the wildcard symbol column.

#### `lightmotif-tfmpvalue`
- Invert decay in `TfmPvalue` to reduce rounding errors when computing granularity.
- Use a fast integer hashing algorithm for `i64` keys in maps used for recording *Q*-values.
- Compute the optimal column permutation to accelerate the computation of score distributions.

### Removed

#### `lightmotif-transfac`
Deprecate crate in favour of `lightmotif-io`.


## [v0.5.1] - 2023-08-31
[v0.5.1]: https://github.com/althonos/lightmotif/compare/v0.5.0...v0.5.1

### Fixed

#### `lightmotif`
- Compilation for Arm NEON platforms.


## [v0.5.0] - 2023-08-31
[v0.5.0]: https://github.com/althonos/lightmotif/compare/v0.4.0...v0.5.0

### Added

#### `lightmotif`
- Arm NEON implementation of `Threshold` and `Encode`.
- `Alphabet::as_str` method to get the symbols of an alphabet as a string.
- `DenseMatrix::fill` method to fill a dense matrix with a constant value.
- Convenience getters and conversion traits to `StripedSequence`.
- `Stripe` trait to implement striping of an encoded sequence with SIMD.
- Dynamic dispatched pipeline selecting the best implementation as runtime.
- `PartialEq` implementation for `EncodedSequence`.

#### `lightmotif-py`
- Buffer and copy protocols for `StripedSequence` and `EncodedSequence`.
- Indexing support to `EncodedSequence`.

#### `lightmotif-tfmpvalue`
- Convenience methods to access the wrapped `ScoringMatrix` reference in `TfmPvalue`.

### Changed

#### `lightmotif`
- `Encode::encode` now returns an `EncodedSequence` instead of a raw `Vec`.
- Performance improvements for `Encode` for AVX2 and NEON by removing non-const function calls in loop.
- Performance improvements for `Threshold` by skipping the index buffer initialization.
- Avoid buffer initialization when allocating a new buffer in `EncodedSequence::encode`.
- Require `Symbol` implementors to implement `Eq`.

#### `lightmotif-py`
- Use the dynamic dispatch pipeline to run vectorized operations.

#### `lightmotif-tfmpvalue`
- Make `TfmPvalue` generic over the type of reference to the wrapped `ScoringMatrix`.

### Fixed

#### `lightmotif`
- `Debug` implementation of `DenseMatrix` crashing when attempting to render the padding bytes.


## [v0.4.0] - 2023-08-10
[v0.4.0]: https://github.com/althonos/lightmotif/compare/v0.3.0...v0.4.0

### Changed

#### `lightmotif`
- Improve `DenseMatrix::resize` performance when downsizing.
- Explicitly panic when sequence is too long to be processed with `u32` indices in AVX2 and SSE2.
- Reorganize `DenseMatrix` column alignment and index storage.
- Improve `Score` performance by using pointers instead of slices in SIMD loops.
- Rename `DenseMatrix::columns_effective` to `DenseMatrix::stride`.
- Use streaming intrinsics to store data in AVX2 and SSE2 implementations.
- Rename `BestPosition` trait to `Maximum`.

#### `lightmotif-py`
- Avoid error on missing symbols in `CountMatrix.__init__`

### Added

#### `lightmotif`
- `Threshold` trait to find all position above a certain score in a `StripedScores` matrix.
- `Encode` trait to encode an ASCII sequence into a `Vec<Symbol>`.
- AVX2 implementation of `Score` using `gather` instead of `permute` for protein alphabets.
- `From<Vec<_>>` and `Default` trait implementations to `EncodedSequence`.
- `Alphabet` methods to operate on ASCII strings.
- `StripedScores.is_empty` method to check if a `StripedScores` contains any score.

#### `lightmotif-py`
- `StripedScores.threshold` method wrapping the `Threshold` pipeline operation.
- `StripedScores.max` and `StripedScores.argmax` methods to get the best score and best position.

### Fixed

#### `lightmotif`
- `Score` causing an overflow when given a sequence shorter than the PSSM.
- `Maximum` trait returns the smallest position on equal maxima.


## [v0.3.0] - 2023-06-25
[v0.3.0]: https://github.com/althonos/lightmotif/compare/v0.2.0...v0.3.0

### Changed
- Rewrite the SSE2 maximum search implementation using a generic number of columns.
- Refactor `lightmotif::pwm` to avoid infinite odds-ratio for columns with zero background frequencies.

### Added
- `lightmotif-tfmpvalue` crate implementing the TFMPvalue for computing p-values for a `ScoringMatrix`.
- `DenseMatrix::from_rows` method to create a dense matrix from an iterable of rows.
- `PartialEq` implementation for matrices in `lightmotif`.
- Methods to compute the minimum and maximum scores of a `ScoringMatrix`.


## [v0.2.0] - 2023-05-15
[v0.2.0]: https://github.com/althonos/lightmotif/compare/v0.1.1...v0.2.0

### Changed
- Crate structure to avoid cluttering the main `lightmotif` module namespace.
- Swizzling used in the SSSE3 implementation to make it require SSE2 only.
- TRANSFAC parser to support parsing sections in arbitrary order and accept additional metadata.
- Use `memchr` to parse lines faster in TRANSFAC parser.
- Use `typenum` and `generic-array` to handle constant matrix dimensions.
- Make `Score` trait generic over the number of columns in the striped sequence.

### Added
- Accessors for some of the attributes of `lightmotif_transfac::Matrix`.
- Pipeline method to extract the best position from a `StripedScore` matrix.
- Child trait for alphabet complementation.
- Methods for reverse-complementing all matrices from `lightmotif::pwm`.
- `Alphabet::symbols` method to get all the symbols of an alphabet.
- `StripedSequence::encode` constructor to encode and stripe a text sequence without allocating an extra `EncodedSequence`.
- Iterator methods and helper struct for `StripedScores`.
- `Protein` alphabet to `lightmotif::abc`.
- `DenseMatrix::uninitialized` constructor to allocate a dense matrix without filling its contents.
- `lightmotif::num` module with `typenum` re-exports and additional `StrictlyPositive` marker trait.
- Arm NEON implementation of the position scoring algorithm.
- `Display` implementation for `EncodedSequence` instead of an arbitrary `ToString` implementation.


## [v0.1.1] - 2023-05-04
[v0.1.1]: https://github.com/althonos/lightmotif/compare/v0.1.0...v0.1.1

### Added
- Helper crate to detect CPU features support at runtime.

### Fixed
- AVX2 code being imported on x86-64 platforms without checking for OS support.
- AVX2-enabled extension always being compiled even on platforms with no AVX2 support.

### Removed
- `built` and `pyo3-built` build dependencies (causing issues with workspaces).


## [v0.1.0] - 2023-05-04
[v0.1.0]: https://github.com/althonos/lightmotif/compare/4ccf9596b7...v0.1.0

Initial release.