Link Search Menu Expand Document

Get Started

Overall FITS structure. FITS is an HDU list. Each HDU consists of a header and data block. A header is a collection of 80-character ASCII strings as “keyword-value-note” type records. A data block is a byte stream in big-endian order with a specification in a header.

To integrate with the project, add the source library directory to the search path.

Example 1: Edit HDU

Edit a header and data of the HDU without considering its extension specification, see demo edithead and editdata.

  1. Include a reference to DeLaFitsCommon and DeLaFitsClasses units in your project

  2. Create the stream with data in FITS format: open a file

     Stream := TFileStream.Create('demo-image.fits', fmOpenReadWrite);
    
  3. Parse the stream: create a FITS container. A container object will contain the HDU list

     Container := TFitsContainer.Create(Stream);
     for I := 0 to Container.Count - 1 do
       HDU := Container.Umits[I];
    
  4. Get the header of the selected HDU. A header object is a list of “keyword-value-note” records

     Head := HDU.Head;
     for I := 0 to Head.Count - 1 do
     begin
       Key  := Head.Keywords[I];
       Valu := Head.ValuesInteger[I];
       Note := Head.Notes[I];
     end;
    
  5. Edit or insert a new header value

     Index := Head.IndexOf('DATE-OBS');
     if Index < 0 then
       Head.AddDateTime('DATE-OBS', Now, 'Add datetime')
     else
       Head.ValuesDateTime[Index] := Now;
    
  6. Get the data object of the selected HDU. Usable data size less than or equal to real

     Data := HDU.Data;
     Cize := Data.Cize; // useful data size
     Size := Data.Size; // real data size
    
  7. Read and edit a data block as a byte stream

     var Chunk: array of Byte;
     ...
     SetLength(Chunk, Cize div 1000);
     Data.Read(0, Length(Chunk), Chunk[0]);
     Chunk[0] := 255;
     Chunk[1] := 255;
     Data.Write(0, Length(Chunk), Chunk[0]);
    
  8. Release resources

     Container.Free;
     Stream.Free;
    

Example 2: Edit IMAGE

Edit the physical values of the IMAGE extension data.

  1. Include a reference to DeLaFitsCommon, DeLaFitsClasses and DeLaFitsImage units in your project

  2. Create the FITS container: open and parse a file

     Stream    := TFileStream.Create('demo-image.fits', fmOpenReadWrite);
     Container := TFitsContainer.Create(Stream);
    
  3. Cast the HDU as an IMAGE extension

     HDU := Container.Umits[0];
     if HDU.Coclass(TFitsImage) then
       Image := HDU.Reclass(TFitsImage) as TFitsImage;
    
  4. Get the data object of the IMAGE

     Data  := Image.Data;
     Size  := Data.Size;  // real data size
     Cize  := Data.Cize;  // useful data size
     Count := Data.Count; // pixels count in a usable data block
    
  5. Read and edit a data block as a sequence of pixels (physical values)

     var Chunk: array of Double;
     ...    
     SetLength(Chunk, Count div 1000);
     Data.ReadElems(0, Length(Chunk), TA64f(Chunk));
     Chunk[0] := Chunk[0] / 2;
     Chunk[1] := Chunk[1] / 2;
     Data.WriteElems(0, Length(Chunk), TA64f(Chunk));
    
  6. Release resources

     Container.Free;
     Stream.Free;
    

Example 3: Create IMAGE

Add a new instance of the IMAGE extension to the FITS container, see demo makeimage.

  1. Include a reference to DeLaFitsCommon, DeLaFitsClasses and DeLaFitsImage units in your project

  2. Create a new file with empty the FITS container

     Stream    := TFileStream.Create('new-image.fits', fmCreate);
     Container := TFitsContainer.Create(Stream);
    
  3. Create a spec of a new IMAGE instance: set BITPIX and dataset size

     Spec := TFitsImageSpec.Create(bi16c, [1000, 2000]);
    
  4. Add a new instance of IMAGE

     Image := Container.Add(TFitsImage, Spec) as TFitsImage;
    
  5. Edit a header and data of the new IMAGE instance

     Head := Image.Head;
     Data := Image.Data;
    
  6. Release resources

     Spec.Free;
     Container.Free;
     Stream.Free;
    

Example 4: Render IMAGE

Create a Bitmap from the data region of the IMAGE extension, see demo renderimage.

  1. Include a reference to DeLaFitsCommon, DeLaFitsClasses and DeLaFitsPicture units in your project

  2. Create the FITS container: open and parse a file

     Stream    := TFileStream.Create('demo-image.fits', fmOpenReadWrite);
     Container := TFitsContainer.Create(Stream);
    
  3. Cast some HDU as a Picture of the IMAGE extension

     for I := 0 to Container.Count - 1 do
       Picture := Container.Reclass(0, TFitsPicture) as TFitsPicture;
    
  4. Get the Frame object of the Picture. The Frame is a two-dimensional array of NAXIS1 x NAXIS2 elements from IMAGE data

     for I := 0 to Picture.Frames.Count - 1 do
       Frame := Picture.Frames[I];
    
  5. Set a Frame region to render

     Region := ToRegion(0, 0, Frame.SceneWidth div 2, Frame.SceneHeight div 2);
    
  6. Create a new Bitmap and render the Frame region

     Bitmap := TBitmap.Create;
     Frame.RenderScene(Bitmap, Region);
    
  7. Release resources

     Bitmap.Free;
     Container.Free;
     Stream.Free;
    

Example 5: Edit ASCII-TABLE

Edit the physical values of the ASCII-TABLE extension data.

  1. Include a reference to DeLaFitsCommon, DeLaFitsClasses and DeLaFitsAscTable units in your project

  2. Create the FITS container: open and parse a file

     Stream    := TFileStream.Create('demo-asctable.fits', fmOpenReadWrite);
     Container := TFitsContainer.Create(Stream);
    
  3. Cast the HDU as an ASCII-TABLE extension

     HDU := Container.Umits[1];
     if HDU.Coclass(TFitsAscTable) then
       Table := HDU.Reclass(TFitsAscTable) as TFitsAscTable;
    
  4. Get the data object of the ASCII-TABLE

     Data     := Table.Data;
     ColCount := Data.ColCount; // number of columns in the table
     RowCount := Data.RowCount; // number of rows in the table
    
  5. Read and edit a table fields as physical values

     var Chunk: array of Double;
     ...
     Index := 4;
     if Data.ColsNature[Index] = anFloat then
     begin
       SetLength(Chunk, RowCount);
       Data.ReadCells(Index, 0, RowCount, TA64f(Chunk));
       Chunk[0] := Chunk[0] / 2;
       Chunk[1] := Chunk[1] / 2;
       Data.WriteCells(Index, 0, RowCount, TA64f(Chunk));
     end;
    
  6. Release resources

     Container.Free;
     Stream.Free;
    

Example 6: Create ASCII-TABLE

Add a new instance of the ASCII-TABLE extension to the FITS container, see demo makeasctable.

  1. Include a reference to DeLaFitsCommon, DeLaFitsClasses and DeLaFitsAscTable units in your project

  2. Create a new file with empty the FITS container

     Stream    := TFileStream.Create('new-asctable.fits', fmCreate);
     Container := TFitsContainer.Create(Stream);
    
  3. Add a simple Primary HDU as the ASCII-TABLE extension cannot be primary

     Container.Add(TFitsUmit, nil);
    
  4. Create a spec of a new ASCII-TABLE instance: set column array and row count. Set the column position as 1 the specification object will correctly calculate this parameter

     var C1, C2, C3, C4, C5: TAscColumn;
     ...
     C1 := AscColumnCreateString(1,     10, 'MYCOL1');
     C2 := AscColumnCreateString(1,      1, 'MYCOL2'); // ~ boolean
     C3 := AscColumnCreateNumber(1, rep16c, 'MYCOL3');
     C4 := AscColumnCreateNumber(1, rep16u, 'MYCOL4');
     C5 := AscColumnCreateNumber(1, rep32f, 'MYCOL5');
     Spec := TFitsAscTableSpec.Create([C1, C2, C3, C4, C5], 10);
    
  5. Add a new instance of ASCII-TABLE

     Table := Container.Add(TFitsAscTable, Spec) as TFitsAscTable;
    
  6. Edit a header and data of the new ASCII-TABLE instance

     Head := Table.Head;
     Data := Table.Data;
    
  7. Release resources

     Spec.Free;
     Container.Free;
     Stream.Free;