Skip to content

Commit 3e45ddf

Browse files
authored
All OverrideCycle total counts on DataSection must grow to the Reads-Sections maximum value by adding the N-tag
1 parent ef8e48e commit 3e45ddf

16 files changed

+199
-77
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ See [GitHub releases](https://github.com/mll-lab/php-utils/releases).
99

1010
## Unreleased
1111

12+
## v2.2.1
13+
14+
### Changed
15+
16+
- All OverrideCycle total counts on DataSection must grow to the Reads-Sections maximum value by adding the N-tag
17+
1218
## v2.2.0
1319

1420
### Added

src/IlluminaSampleSheet/V2/BclConvert/BclConvertSection.php

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace MLL\Utils\IlluminaSampleSheet\V2\BclConvert;
44

5-
use Illuminate\Support\Collection;
65
use MLL\Utils\IlluminaSampleSheet\Section;
76
use MLL\Utils\IlluminaSampleSheet\V2\ReadsSection;
87

@@ -30,37 +29,6 @@ public function convertSectionToString(): string
3029

3130
public function makeReadsSection(): ReadsSection
3231
{
33-
$dataRows = new Collection($this->dataSection->dataRows);
34-
35-
$countFromCycleTypeWithCount = fn (CycleTypeWithCount $cycleTypeWithCount): int => $cycleTypeWithCount->count;
36-
37-
$read1Cycles = $dataRows->max(
38-
fn (BclSample $dataRow) => (new Collection($dataRow->overrideCycles->read1->cycles))
39-
->sum($countFromCycleTypeWithCount)
40-
);
41-
$index1Cycles = $dataRows->max(
42-
fn (BclSample $dataRow) => (new Collection($dataRow->overrideCycles->index1->cycles))
43-
->sum($countFromCycleTypeWithCount)
44-
);
45-
46-
$index2Cycles = $dataRows->max(
47-
fn (BclSample $dataRow) => $dataRow->overrideCycles->index2 instanceof OverrideCycle
48-
? (new Collection($dataRow->overrideCycles->index2->cycles))
49-
->sum($countFromCycleTypeWithCount)
50-
: null
51-
);
52-
$read2Cycles = $dataRows->max(
53-
fn (BclSample $dataRow) => $dataRow->overrideCycles->read2 instanceof OverrideCycle
54-
? (new Collection($dataRow->overrideCycles->read2->cycles))
55-
->sum($countFromCycleTypeWithCount)
56-
: null
57-
);
58-
59-
assert(is_int($read1Cycles));
60-
assert(is_int($index1Cycles));
61-
assert(is_int($read2Cycles) || is_null($read2Cycles));
62-
assert(is_int($index2Cycles) || is_null($index2Cycles));
63-
64-
return new ReadsSection($read1Cycles, $index1Cycles, $read2Cycles, $index2Cycles);
32+
return $this->dataSection->makeReadsSection();
6533
}
6634
}

src/IlluminaSampleSheet/V2/BclConvert/DataSection.php

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
namespace MLL\Utils\IlluminaSampleSheet\V2\BclConvert;
44

5+
use Illuminate\Support\Collection;
56
use MLL\Utils\IlluminaSampleSheet\Section;
7+
use MLL\Utils\IlluminaSampleSheet\V2\ReadsSection;
68

79
class DataSection implements Section
810
{
9-
/** @var array<BclSample> */
10-
public array $dataRows = [];
11+
/** @var Collection<int, BclSample> */
12+
public Collection $dataRows;
13+
14+
public function __construct()
15+
{
16+
$this->dataRows = new Collection();
17+
}
1118

1219
public function addSample(BclSample $bclSample): void
1320
{
14-
$this->dataRows[] = $bclSample;
21+
$this->dataRows->add($bclSample);
1522
}
1623

1724
public function convertSectionToString(): string
@@ -49,4 +56,62 @@ protected function generateDataHeaderByProperties(array $samplePropertiesOfFirst
4956

5057
return implode(',', $samplePropertiesOfFirstSample);
5158
}
59+
60+
public function makeReadsSection(): ReadsSection
61+
{
62+
return new ReadsSection(
63+
$this->maxRead1Cycles(),
64+
$this->maxIndex1Cycles(),
65+
$this->maxRead2Cycles(),
66+
$this->maxIndex2Cycles()
67+
);
68+
}
69+
70+
public function maxRead1Cycles(): int
71+
{
72+
$max = $this->dataRows
73+
->max(fn (BclSample $dataRow): int => $dataRow
74+
->overrideCycles
75+
->read1
76+
->sumCountOfAllCycles());
77+
assert(is_int($max));
78+
79+
return $max;
80+
}
81+
82+
public function maxRead2Cycles(): ?int
83+
{
84+
$max = $this->dataRows->max(
85+
fn (BclSample $dataRow): ?int => $dataRow->overrideCycles->read2 instanceof OverrideCycle
86+
? $dataRow->overrideCycles->read2->sumCountOfAllCycles()
87+
: null
88+
);
89+
assert(is_int($max) || is_null($max));
90+
91+
return $max;
92+
}
93+
94+
public function maxIndex1Cycles(): int
95+
{
96+
$index1Cycles = $this->dataRows
97+
->max(fn (BclSample $dataRow): int => $dataRow
98+
->overrideCycles
99+
->index1
100+
->sumCountOfAllCycles());
101+
assert(is_int($index1Cycles));
102+
103+
return $index1Cycles;
104+
}
105+
106+
public function maxIndex2Cycles(): ?int
107+
{
108+
$index2Cycles = $this->dataRows->max(
109+
fn (BclSample $dataRow): ?int => $dataRow->overrideCycles->index2 instanceof OverrideCycle
110+
? $dataRow->overrideCycles->index2->sumCountOfAllCycles()
111+
: null
112+
);
113+
assert(is_int($index2Cycles) || is_null($index2Cycles));
114+
115+
return $index2Cycles;
116+
}
52117
}

src/IlluminaSampleSheet/V2/BclConvert/OverrideCycle.php

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,41 @@ class OverrideCycle
77
/** @var array<CycleTypeWithCount> */
88
public array $cycles;
99

10-
/** @param array<CycleTypeWithCount> $firstCycle */
11-
public function __construct(array $firstCycle)
10+
/** @param array<CycleTypeWithCount> $cycles */
11+
public function __construct(array $cycles)
1212
{
13-
$this->cycles = $firstCycle;
13+
$this->cycles = $cycles;
1414
}
1515

16-
public function toString(): string
16+
/** @param bool|null $isSecondIndexAndForwardDirection null if it is not the secondIndex, true if it is the secondIndex and forwardDirection, false if it is the secondIndex and reverseDirection */
17+
public function toString(int $fillUpToMax, ?bool $isSecondIndexAndForwardDirection): string
1718
{
18-
return implode('', array_map(
19+
$countOfAllCycleTypes = $this->sumCountOfAllCycles();
20+
assert($countOfAllCycleTypes <= $fillUpToMax, 'The sum of all cycle types must be less than or equal to the fill up to max value.');
21+
22+
$rawOverrideCycle = implode('', array_map(
1923
fn (CycleTypeWithCount $cycle): string => $cycle->toString(),
2024
$this->cycles
2125
));
26+
27+
if ($countOfAllCycleTypes === $fillUpToMax) {
28+
return $rawOverrideCycle;
29+
}
30+
31+
$remainingCycles = 'N' . ($fillUpToMax - $countOfAllCycleTypes);
32+
33+
return (bool) $isSecondIndexAndForwardDirection
34+
? $remainingCycles . $rawOverrideCycle
35+
: $rawOverrideCycle . $remainingCycles;
36+
}
37+
38+
public function sumCountOfAllCycles(): int
39+
{
40+
return array_sum(
41+
array_map(
42+
fn (CycleTypeWithCount $cycleTypeWithCount): int => $cycleTypeWithCount->count,
43+
$this->cycles
44+
)
45+
);
2246
}
2347
}

src/IlluminaSampleSheet/V2/BclConvert/OverrideCycles.php

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace MLL\Utils\IlluminaSampleSheet\V2\BclConvert;
44

55
use MLL\Utils\IlluminaSampleSheet\IlluminaSampleSheetException;
6+
use MLL\Utils\IlluminaSampleSheet\V2\HeaderSection;
67

78
class OverrideCycles
89
{
@@ -14,24 +15,38 @@ class OverrideCycles
1415

1516
public ?OverrideCycle $read2;
1617

17-
public function __construct(string $read1, string $index1, ?string $index2, ?string $read2)
18+
private DataSection $dataSection;
19+
20+
public function __construct(DataSection $dataSection, string $read1, string $index1, ?string $index2, ?string $read2)
1821
{
1922
$this->read1 = $this->makeOverrideCycle($read1);
2023
$this->index1 = $this->makeOverrideCycle($index1);
2124
$this->index2 = $index2 !== null ? $this->makeOverrideCycle($index2) : null;
2225
$this->read2 = $read2 !== null ? $this->makeOverrideCycle($read2) : null;
26+
$this->dataSection = $dataSection;
2327
}
2428

2529
public function toString(): string
2630
{
31+
$dataSection = $this->dataSection;
32+
33+
if ($this->index2 instanceof OverrideCycle) {
34+
$maxIndex2Cycles = $dataSection->maxIndex2Cycles();
35+
if ($maxIndex2Cycles === null) {
36+
throw new IlluminaSampleSheetException('MaxIndex2Cycles is required when Index2 is set.');
37+
}
38+
39+
$index2 = $this->index2->toString($maxIndex2Cycles, HeaderSection::isForwardIndexOrientation());
40+
} else {
41+
$index2 = null;
42+
}
43+
2744
return implode(';', array_filter([
28-
$this->read1->toString(),
29-
$this->index1->toString(),
30-
$this->index2 instanceof OverrideCycle
31-
? $this->index2->toString()
32-
: null,
45+
$this->read1->toString($dataSection->maxRead1Cycles(), null),
46+
$this->index1->toString($dataSection->maxIndex1Cycles(), null),
47+
$index2,
3348
$this->read2 instanceof OverrideCycle
34-
? $this->read2->toString()
49+
? $this->read2->toString($dataSection->maxRead1Cycles(), null)
3550
: null,
3651
]));
3752
}

src/IlluminaSampleSheet/V2/HeaderSection.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
class HeaderSection implements Section
88
{
99
protected const FILE_FORMAT_VERSION = '2';
10+
public const INDEX_ORIENTATION_FORWARD = 'Forward';
1011

1112
protected string $fileFormatVersion = self::FILE_FORMAT_VERSION;
1213

@@ -26,17 +27,25 @@ public function __construct(string $runName)
2627
$this->runName = $runName;
2728
}
2829

30+
public static function isForwardIndexOrientation(): bool
31+
{
32+
// Added this static method to explicitly display that this flag influences Index2 in OverrideCycles.
33+
return HeaderSection::indexOrientation() === HeaderSection::INDEX_ORIENTATION_FORWARD;
34+
}
35+
2936
public function setCustomParam(string $paramName, string $paramValue): void
3037
{
3138
$this->customParams['Custom_' . $paramName] = $paramValue;
3239
}
3340

3441
public function convertSectionToString(): string
3542
{
43+
$indexOrientation = self::indexOrientation();
3644
$headerLines = [
3745
'[Header]',
3846
"FileFormatVersion,{$this->fileFormatVersion}",
3947
"RunName,{$this->runName}",
48+
"IndexOrientation,{$indexOrientation}",
4049
];
4150
if (! is_null($this->runDescription)) {
4251
$headerLines[] = "RunDescription,{$this->runDescription}";
@@ -53,4 +62,10 @@ public function convertSectionToString(): string
5362

5463
return implode("\n", $headerLines) . "\n";
5564
}
65+
66+
public static function indexOrientation(): string
67+
{
68+
// Only support the default IndexOrientation (Forward) for now.
69+
return self::INDEX_ORIENTATION_FORWARD;
70+
}
5671
}

tests/BavarianHolidaysTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Carbon\Carbon;
66
use MLL\Utils\BavarianHolidays;
7+
use PHPUnit\Framework\Attributes\DataProvider;
78
use PHPUnit\Framework\TestCase;
89

910
final class BavarianHolidaysTest extends TestCase
@@ -15,24 +16,24 @@ public function testNameHoliday(): void
1516
self::assertSame(BavarianHolidays::OSTERSONNTAG, BavarianHolidays::nameHoliday(self::easterSunday2019()));
1617
}
1718

18-
#[\PHPUnit\Framework\Attributes\DataProvider('businessDays')]
1919
/** @dataProvider businessDays */
20+
#[DataProvider('businessDays')]
2021
public function testBusinessDays(Carbon $businessDay): void
2122
{
2223
self::assertTrue(BavarianHolidays::isBusinessDay($businessDay));
2324
self::assertFalse(BavarianHolidays::isHoliday($businessDay));
2425
}
2526

26-
#[\PHPUnit\Framework\Attributes\DataProvider('holidays')]
2727
/** @dataProvider holidays */
28+
#[DataProvider('holidays')]
2829
public function testHolidays(Carbon $holiday): void
2930
{
3031
self::assertFalse(BavarianHolidays::isBusinessDay($holiday));
3132
self::assertTrue(BavarianHolidays::isHoliday($holiday));
3233
}
3334

34-
#[\PHPUnit\Framework\Attributes\DataProvider('weekend')]
3535
/** @dataProvider weekend */
36+
#[DataProvider('weekend')]
3637
public function testWeekend(Carbon $weekend): void
3738
{
3839
self::assertFalse(BavarianHolidays::isBusinessDay($weekend));

tests/CSVArrayTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace MLL\Utils\Tests;
44

55
use MLL\Utils\CSVArray;
6+
use PHPUnit\Framework\Attributes\DataProvider;
67
use PHPUnit\Framework\TestCase;
78

89
/** @phpstan-import-type CSVPrimitive from CSVArray */
@@ -46,7 +47,7 @@ public static function csvAndArrayStringValues(): iterable
4647
*
4748
* @param array<int, array<string, string>> $array
4849
*/
49-
#[\PHPUnit\Framework\Attributes\DataProvider('csvAndArrayStringValues')]
50+
#[DataProvider('csvAndArrayStringValues')]
5051
public function testStringValues(string $csv, array $array): void
5152
{
5253
self::assertSame($array, CSVArray::toArray($csv));

tests/IlluminaSampleSheet/V1/DualIndexTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
use MLL\Utils\IlluminaSampleSheet\IlluminaSampleSheetException;
66
use MLL\Utils\IlluminaSampleSheet\V1\DualIndex;
7+
use PHPUnit\Framework\Attributes\DataProvider;
78
use PHPUnit\Framework\TestCase;
89

910
class DualIndexTest extends TestCase
1011
{
1112
/** @dataProvider provideValidDualIndexes */
13+
#[DataProvider('provideValidDualIndexes')]
1214
public function testValidate(
1315
string $i7IndexID,
1416
string $index,

0 commit comments

Comments
 (0)