From 462d2350f0d1ffc2362d2a2da93b5e1ffb95375a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20P=2E?= Date: Thu, 26 Sep 2024 16:23:31 +0200 Subject: [PATCH] Parse FITS keywords --- src/Fits.php | 20 ++++++++++++++------ src/FitsHeader.php | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/Keyword.php | 18 ++++++++++++++++++ 3 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 src/Keyword.php diff --git a/src/Fits.php b/src/Fits.php index d9a2f8d..f3d06b6 100644 --- a/src/Fits.php +++ b/src/Fits.php @@ -17,6 +17,7 @@ class Fits private $byteStream; private string $path; public readonly int $size; + public readonly string $headerBlock; /** * @throws InvalidFitsException, InvalidPathException @@ -34,6 +35,8 @@ class Fits if (! $this->validate()) { throw new InvalidFitsException('The opened file is not a valid FITS image (invalid block size)'); } + + $this->headerBlock = $this->extractHeader(); } /** * Validate the given FITS file based on block sizes @@ -52,11 +55,16 @@ class Fits return true; } /** - * @todo Return FitsHeader object - * @return string + * @return FitsHeader */ - #[\ReturnTypeWillChange] - public function header(): string + public function header(): FitsHeader + { + return new FitsHeader($this->headerBlock); + } + /** + * Extract the FITS header block as a string + */ + private function extractHeader(): string { $contents = fread($this->byteStream, $this->size); $end = strpos($contents, 'END'); @@ -66,8 +74,8 @@ class Fits return substr($contents, 0, $headerEnd); } - public function fromPath(string $path): void + public function writeTo(string $path): void { - $this->byteStream = fopen($path, 'rb'); + // TODO } } diff --git a/src/FitsHeader.php b/src/FitsHeader.php index 068256f..6a0e26f 100644 --- a/src/FitsHeader.php +++ b/src/FitsHeader.php @@ -4,7 +4,52 @@ declare(strict_types=1); namespace Dumbastro\FitsPhp; +use Dumbastro\FitsPhp\Keyword; + class FitsHeader { + private string $headerBlock; + /** + * @var Keyword[] $keywords + */ + public readonly array $keywords; + + public function __construct(string $headerBlock) + { + $this->headerBlock = $headerBlock; + $this->keywords = $this->readKeywords(); + } + /** + * Initialize the keyword records array + * + * From the spec: each keyword record, including + * any comments, is at most 80 bytes long + * @return Keyword[] + */ + private function readKeywords(): array + { + $records = str_split($this->headerBlock, 80); + + $records = array_filter( + $records, + fn (string $r) => trim($r) !== '' && !str_starts_with($r, 'END') + ); + + $keywords = []; + + foreach ($records as $record) { + $splitByComment = explode('/', $record); + $comment = isset($splitByComment[1]) ? trim($splitByComment[1]) : null; + $nameValue = explode('=', $splitByComment[0]); + + $keywords[] = new Keyword( + name : trim($nameValue[0]), + value : trim($nameValue[1]), + comment : $comment, + ); + } + + return $keywords; + } } diff --git a/src/Keyword.php b/src/Keyword.php new file mode 100644 index 0000000..0fb55ce --- /dev/null +++ b/src/Keyword.php @@ -0,0 +1,18 @@ +