fits(3tcl)

πŸŽ€ NAME πŸŽ€

fits β€” Tcl interface to FITS Files

okay so bestie, this is fits(3tcl) and it's literally the Tcl doorway into FITS files. FITS is the astronomy file format, and this whole page is your group chat with it. Sit down, hydrate, we're going through every single flag together. 🫢


✨ SYNOPSIS ✨

fits (open|info|close)

🌈 Handling FitsFile objects 🌈

πŸ’– fits open fileName mode ?objName?

Make a FitsFile object, open the file, and read the header of the current HDU. (Go read the CFITSIO web pages or docs to learn about its "Extended File Name Syntax" β€” it's giving lore, iykyk.) mode can be 0 (read only) or 1 (read and write). If you don't hand over an objName, a name gets auto-assigned, no stress. You can also create a brand new empty FITS file by setting mode to 2 β€” and heads up, in that case if the named file already exists, it gets overwritten, so like, be careful queen. Returns objName, which is the handle you'll use in most of the methods. πŸ‘‘

πŸ¦‹ fits info ?objName ...?

Returns a list of all the existing objects, or the named ones (regular expressions are supported, slay). Each entry looks like {objName fileName mode CHDU hduType} where CHDU is the current HDU (1-primary array, 2-the first extension ...) and hduType is the type of the HDU (0-image, 1-ASCII table, 2-Binary table).

🌸 objName move ?+/-?n

If n has a +/- sign, then move n units relative to the CHDU. Otherwise move to the *n*th HDU. Returns the extension type of the new HDU: 0-image, 1-ASCII table, 2-Binary Table.

πŸ’… objName close

Delete the object objName. Bye bestie. πŸ‘‹

🧚 fits close

Delete all the existing objects. Full clean slate energy.


⭐ Getting information about the CHDU ⭐

πŸ“ objName info chdu

Return the CHDU. 1=primary, 2=first extension, etc.

πŸ“ objName info filesize

Return the size of the file (in units of 2880 bytes).

πŸ“ objName info hdutype

Return Primary array, Image extension, Binary Table, or ASCII Table.

πŸ“ objName info imgdim

Return the dimensions of the image if the CHDU is an image extension.

πŸ“ objName info ncols

Return the number of columns in the table if the CHDU is a table extension.

πŸ“ objName info nrows

Return the number of rows in the table if the CHDU is a table extension.

πŸ“ objName info nkwds

Return the number of keywords in the header of the CHDU.

πŸ’œ objName info column ?-exact? ?colList?

With zero arguments, return a list of all the column names in the table if the CHDU is a table extension. If colList is present, you get detailed info about the listed columns, using regular expression name comparisons, returned like this:

{Name Type Unit DisplayFormat DefaultFormat ColumnWidth isOffset isScaled defaultNull}

where

  • Name β€” name of the column (TTYPE keyword)
  • Type β€” type of the column (TFORM keyword)
  • Unit β€” unit of the column (TUNIT keyword)
  • DisplayFormat β€” format for display (TDISP keyword)
  • DefaultFormat β€” default format for display (if the TDISP keyword is absent)
  • ColumnWidth β€” the width of the column (in units of characters)
  • isOffset β€” 0 = no offset (no TZERO keyword), 1 = offset
  • isScaled β€” 0 = not scaled (no TSCALE keyword), 1 = scaled
  • defaultNull β€” default NULL value (TNULL keyword)

The -exact option turns off the regular expression matching.


πŸ”₯ Reading data from a FITS file πŸ”₯

🌟 objName dump ?-s/-e/-l?

Return all the keyword records in the current header. These options control how the info gets formatted:

  • (none) β€” return list of all cards in header
  • -s β€” return three lists: {keywords} {values} {comments}
  • -e β€” return a single string containing a newline-separated list of all header records
  • -l β€” return all the keyword names

🌟 objName get keyword ?keyList?

Return a list of {keyword value comment} for all the keywords in keyList (regular expressions supported, obviously). If no keyList is given, return a list of entries for all the keywords in the CHDU. The order in which keywords are listed is undefined, so don't come for me about ordering. (HISTORY and COMMENT keywords are never returned.)

🌟 objName get keyword -num n

Return a list of {keyword value comment} of the *n*th keyword.

🌟 objName get wcs ?RAcol DecCol?

Return a list of the WCS parameters β€” {xrval yrval xrpix yrpix xinc yinc rot ctype} β€” for the CHDU. If the current HDU is a table, supply the RAcol and DecCol parameters specifying the two columns (as names or column numbers) containing WCS data. Use defaults for any missing WCS keywords: 1.0 for xinc/yinc; none for ctype; and 0.0 or all others. If the RA/Dec identity of the columns (or image axes) aren't known, an extra WCS parameter β€” wcsSwap β€” can be obtained which, when on, indicates that the X parameters are for Dec instead of RA. Turn this option on with fits option wcsSwap 1.

🌟 objName get wcs -m ?Col1 ...?

Similar to above, but the info comes back in new-style format, allowing arbitrary matrix transforms. Return value is {refVals refPix matrix types projections} where each item (except matrix) contains a list of the given information for each image dimension or table column; matrix is the rotation, scale, skew, NxN transformation matrix given as {cd11 .. cd1N cd21 .. cd2N .. cdNN}. The wcsSwap option has no effect on this command β€” you gotta check the types values yourself to see if the RA and Dec transforms are backwards.

🌟 objName get image ?firstElem? ?numElem?

Read data elements from the current IMAGE extension and return them in a list. With no parameters at all, the entire image gets returned. If only firstElem is given, return just one element.

🌟 objName get table ?-c? ?-noformat? ?colList? ?rows?

Read a block of a table and return list(s) of data. The block range is set in:

  • colList β€” a list of all the columns one wants to read. Reads all columns if it's missing or is *.
  • rows β€” a comma-separated list of row ranges of the form start-end (eg, 3-5,7,9-)
  • -c β€” return data from each column as a separate list
  • -noformat β€” do not format results according to a TDISPn, or default, format

🌟 objName get vtable ?-noformat? colName n ?rows?

Return a list of data in the nth vector element in column colName of the given rows. The -noformat option turns off any TDISPn formatting.


πŸ‘‘ Loading data into memory or to a TCL array πŸ‘‘

When loading data into memory, fitsTcl will normally return address dataType numElements where these are:

  • address β€” Memory address of the data. Can be recovered in C by sscanf(address, "%p", &databuff); with void *databuff
  • dataType
    • 0 - BYTE_DATA 1 byte data
    • 1 - SHORTINT_DATA 2 byte integer
    • 2 - INT_DATA 4 byte integer
    • 3 - FLOAT_DATA 4 byte floating point
    • 4 - DOUBLE_DATA 8 byte floating point
  • numElement β€” Number of data elements in the array

🫢 objName load image ?slice? ?rotate?

Load a full 2D image in the CHDU into memory and return the address address (see above). slice indicates which frame to use if the image is 3D. rotate indicates how many 90-degree counter-clockwise rotations to perform on the image (0-3).

🫢 objName load iblock arrayName firstRow numRows firstCol numCols ?slice?

Load a block (starting from firstCol, firstRow with size numCols x numRows) of image data into a 2-D TCL array arrayName, or into memory if arrayName is --. The indices of the array variable are (firstCol-1 ... firstCol+numCols-1, firstRow-1 ... firstRow+numRows-1). A 1D image will be treated as either a single row or column, depending on the row/column parameters supplied. For a 3D image, slice indicates which frame to use. If arrayName is --, read the data block into memory and return the pointer information: address dataType numElements.

🫢 objName load irows firstRow lastRow ?slice?

🫢 objName load icols firstCol lastCol ?slice?

Read and average together a range of rows or columns of an image. Returns address dataType numElements. dataType will be 3 for all image data types except for double, for which dataType is 4.

🫢 objName load column colName ?defaultNull? ?firstElement?

Load a column of a table into memory and return address dataType numElements. Use the value of defaultNull for NULL values, or internal defaults (normally the data type's maximum value) if NULL or absent. If colName is a vector column, read the firstElement-th element. You can only load numerical columns, so no cute strings sorry.

🫢 objName load vtable colName

Load all elements of the vector column colName and return address dataType numElements.

🫢 objName load tblock ?-noformat? arrayName colList firstRow numRows colIndex ?firstElem?

Load a block of table data into a 2-D TCL array arrayName. colIndex is (almost) the column index of the array to use for the first column read. The first data index is actually (as for images) (colIndex-1,firstRow-1). For scaler columns, firstElem = 1. Without the -noformat flag, values will be returned as strings formatted according to a TDISP keyword or default format based on data type.

🫢 objName load expr ?-rows rows? expression ?defaultNull?

Evaluate the arithmetic expression on each row (or a subset of rows given by rows) of the CHDU's table and return address dataType numElements, using defaultNull as the null value of any NULL results.

🫢 objName load keyword

Load keywords into fitsTcl's internal hash table. One usually will not need to call this routine.

🫢 objName load chdu

Reload the information about the current HDU. One usually will not need to call this routine.

πŸ”₯ Writing to a FITS file πŸ”₯

ok bestie this is where we stop just reading the vibe and start creating it. Every one of these writes into your FITS file, so pay attention bestie, we're making moves πŸ’…


objName insert image bitpix naxis naxesList
objName insert image -p ?bitpix naxis naxesList?
  • Slide in an empty image HDU right after the current HDU β€” or, if you pass -p, it goes in as the primary header (and at the start of the file for a primary array). The image params β€” bitpix naxis naxesList β€” can literally just be left off if you're making a zero-length primary array. no thoughts, just vibes ✨

objName insert table numRows {colNames} {colFormats} ?{colUnits} extensionName?
objName insert table -ascii numRows {colNames} {colFormats} ?{colUnits} {colPosition} extensionName rowWidth?
  • Drops an empty table HDU after the current HDU. Default flavor is BINARY, but slap the -ascii flag on and boom, ASCII table 🌈
  • Heads up: colNames and colFormats are lists and they must be the same length (yes, both empty counts as the same length, icon behaviour honestly).
  • The optional parameters can each be empty too, if you just wanna roll with default/empty values. low maintenance, we love her 🫢

objName insert keyword index record ?formatFlag?
  • Plants a new record at the index-th keyword. If formatFlag is 0, the record gets written exactly as you passed it β€” no edits, no notes. Otherwise it's parsed as a free form keyname value comment and reformatted into the standardized KEYNAME = VALUE / COMMENT (that's the default). it's giving glow-up πŸ’…

objName put keyword ?-num index? record ?formatFlag?
  • Writes a keyword record at position index, or at the position of a pre-existing keyword with the same name, or just appends it if no such keyword exists. Either way she's getting in there πŸ’–
  • record and formatFlag work exactly like the insert keyword situation above, so scroll up bestie.

objName put history historyStr
  • Writes a HISTORY keyword with content historyStr. For the lore. For the archives. πŸŽ€

objName insert column index colName colFormat
  • Inserts an empty column with format colFormat before the index-th column. colFormat is like, for example:
ASCII Table: A15, I10, E12.5, D20.10, F14.6 ...
BINARY Table: 15A, 1I, 1J, 1E, 1D, 1L, 1X, 1B, 1C, 1M

objName add column colName colFormat ?expression?
  • No expression? Just appends an empty column to the CHDU table and returns nothing. Simple. Chill. πŸ¦‹
  • Give it an arithmetic expression though and things get spicy: the indicated column β€” new or old β€” gets filled in with the results of expression evaluated for every single row of the table. periodt.
  • If colName doesn't exist in the current table extension, a new one gets created with format colFormat (see the formats up there ↑).
  • If colFormat is "default", the column gets created based on the data type of the result. cute AND smart πŸ’…
  • Returns 1 or 0 to tell you whether a new column was created (1) or not (0).
  • expression can be in either C or Fortran format, with table columns and keywords referenced by their names. Some samples so you get the vision:
  • 17.2 β€” 17.2 for every row
  • 17 + 4*(PHI > 32) β€” 17 or 21, depending on whether that row of the PHI column is greater than 32
  • sqrt( (X-X0)^2 + (Y-Y0)^2 ) β€” Distance of the (X,Y) column coordinates from the (X0,Y0) keyword values
See the CFITSIO web pages and documentation for more details. (iykyk)

objName insert row index numRows
  • Inserts numRows rows right after the index-th row. boom, more rows, more data, more main character energy πŸ‘‘

objName add row numRows
  • Adds numRows rows at the end of the CHDU table. no drama, just growth 🌸

objName put image firstElem listOfData
  • Writes a block of data to the CHDU image. Careful bestie: the first pixel of an image has firstElem = 1, not zero. Not me making that mistake... anyway πŸ™ˆ

objName put table colName firstElem rowSpan listOfData
  • Writes a list of data to the firstElem-th element of column colName in the CHDU table. (For scalar columns, firstElem is 1.)
  • rowSpan is a single row range of the form start-end, and a - means all rows. so basically - is the "idk all of them" option 🫢

πŸ—‘οΈ Deleting data from a FITS file πŸ—‘οΈ

breaking up is hard but sometimes the file just needs to let that data go πŸ’”


objName delete keyword keyList
  • Deletes the listed keywords, where keyList can be a mix of keyword names and index numbers.
  • > ⚠️ Warning bestie: keywords get deleted individually in sequence, which means the keyword positions change after each deletion. So be super careful when you're deleting multiple keywords by index. It's giving moving target 😭

objName delete cols colList
  • Deletes the listed columns in a table extension. bye girl πŸ’…

objName delete rows firstRow numRows
  • Deletes a block of rows. clean, surgical, iconic.

objName delete rows -expr expression
  • Deletes rows using expression, which must evaluate to a boolean value. Rows where expression evaluates to TRUE get deleted. so true = gone, no cap 🌈

objName delete chdu
  • Deletes the current HDU. The HDU immediately following the deleted one (or the preceding one, if the current HDU was the last one in the file) becomes the new current HDU. glow up via subtraction ✨
  • Returns the extension type of the new HDU: 0-image, 1-ASCII table, 2-Binary Table.

πŸ” Analyzing FITS data πŸ”

detective mode activated πŸ•΅οΈβ€β™€οΈπŸ’–


objName sort ?-merge? colList ?ascendFlags?
  • Sorts table rows using the columns in colList.
  • With -merge present, if multiple rows have identical sort keys, all but one of those rows get deleted. (yes it's aggressive, that's the point πŸ’€)
  • If present, ascendFlags is a list of 1s and 0s saying whether that column gets sorted ascending (1, the default) or descending (0). so 1 = up, 0 = down, we love a clear system πŸ‘‘

objName column -stat colName ?firstElem? ?rows?
  • Returns statistics on the firstElem-th element (1 for scalar columns) of column colName, in this exact order: min firstMinRow max firstMaxRow mean stdDev numData. seven whole values, she's thorough πŸ’…

objName column -minmax colName ?firstElem? ?rows?
  • Returns just the minimum and maximum values of the firstElem-th element (1 for scalar columns) of column colName. the short version, for when you're in a hurry πŸ¦‹

objName histogram ?-weight colName|value? ?-inverse? ?-rows rows? filename {binAxis1} ?{binAxis2} ...?
  • Creates a 1D – 4D histogram from columns in the current table. obsessed.
  • The binning params are the binAxisN parameters, which are lists of the form colName min max binSize, where the last 3 elements can each be -, meaning "default values please".
  • If TLMINn, TLMAXn, and/or TDBINn exist, those values get used for the defaults. Otherwise, for min and max the defaults are the actual min/max values of the data; for binSize the smaller of one-tenth the data span or 1.0 gets picked.
  • A weighting value can be indicated with the -weight option β€” either another column or a numerical constant.
  • The -inverse option says the weight should be 1.0/weight instead of the weighting value itself. flip it and reverse it ✨
  • The histogram can be restricted to certain row ranges with the -rows option.

objName smooth {width height} outfile ?inPrimary?
  • Smooths the current image extension with a boxcar function of dimensions width by height pixels. (Yes, the dimensions must be odd integers. even numbers need not apply πŸ’…)
  • The resulting image lands in a new extension appended to the file outfile.
  • If outfile doesn't exist, the image goes either in the primary or in the first extension, depending on the value of the inPrimary flag. Default behaviour is to place it in an extension. πŸŽ€

🧠 List/Pointer Manipulation 🧠

where the TCL lists and the memory arrays meet, and honestly it's giving crossover episode 🌈


lst2ptr dataList ?dataType? ?naxesList?
  • Converts a TCL list into a memory-resident array. Returns address dataType naxesList (peep the load commands above for that format).
  • Without a dataType, the TCL list gets cast as double values. slay.
  • naxesList gives the vector dimensions of the list. It can be a single number indicating the length of the list (that's the default when it's absent) or a list of numbers which must multiply together to equal the list length.
  • If a list entry contains the string "NULL", the maximum value of the given dataType gets inserted. noted πŸ“

ptr2lst address dataType naxesList
  • Converts a memory pointer into a TCL list. Returns dataList dataType naxesList (see lst2ptr).
  • If an array element contains the maximum value for the given dataType, the string "NULL" gets inserted into the list. symmetry, we love to see it πŸ’–

vexpr ?-ptr? ?-use getDataCallback? expression
  • Does a vector calculation using lists or arrays, where expression is a C-style arithmetic expression. (Ie, do not use $var notation unless you explicitly want variable substitution before passing expression to vexpr.) no accidental substitution bestie, read the fine print πŸ™ˆ
  • With no options, variable references inside expression get interpreted as local TCL lists (or scalars) containing double data, and the result is itself a plain TCL list.
  • With -ptr set, the answer instead comes back as a pointer to a memory-resident array.
  • With either option set, two extra parameters get returned in a list of the form dataList dataType naxesList or address dataType naxesList. cute bonus content ✨
  • The -use option gives you a "callback" routine used for supplying the variable data. It gets called whenever a variable is encountered in the expression, and it's passed a single argument containing the name of the variable.
  • The callback routine should return either "dataList dataType naxesList" or "-ptr address dataType naxesList".
  • If the callback routine doesn't recognize the variable, it should return an empty string β€” then the parser will try to find the variable in the local namespace, just like when no callback is supplied. If you don't want that fallback behaviour, raise an error instead. your call, your rules πŸ’…
  • The callback function can itself check for local variables using the TCL command upvar 1 $varName localName.
  • Here's a sample callback function that assumes the expression contains variables storing the results of a load or lst2ptr command (ie, address dataType naxesList):
proc getPtrData { varName } {
    upvar $varName myName
    if [info exists myName] {
        return [eval list -ptr $myName]
    } else {
        error "Variable doesn't exist"
    }
}
  • And then the following code would calculate the average value of a table column:
set myCol [objName load column X]
vexpr -use getPtrData "sum( (double)myCol ) / nelem( myCol )"
  • By default, a vector with a single-valued naxesList is interpreted as a single vector containing n elements, such that the "sum" function above sums all of the elements.
  • In the context of loading a column though, you actually have an array of n rows with each row containing 1 (or maybe more) elements. To handle that case, you have to use the callback function to provide an naxisList of "1 n" (or "2 m", etc) instead of merely "n". Then each row gets calculated separately and has its own result. 🌸
  • When naxesList has multiple elements, the final element specifies the number of rows.
  • See the CFITSIO web pages and documentation for details on expression syntax. You can also read the fv online help file on expression syntax β€” just note that vexpr can only handle numerical input and output. math only, no chat 🫢

fits free addressList
  • Frees the memory occupied by the data generated by one of the load, lst2ptr, and vexpr commands. clean up after yourself bestie, the memory deserves peace 🧚

🌈 Other commands 🌈

okay bestie, here's the rest of the fitsTcl menu β€” the little extras that make everything go brrr πŸ’… no cap, these are the commands that don't fit in the other sections but are lowkey essential.

  • objName copy filename β€” copy the CHDU into a brand new FITS file. if the CHDU isn't an image array, then an empty primary array gets inserted. it's giving "clone but make it FITS" ✨
  • objName sascii table filename fileMode firstRow numRows colList widthList β€” write the columns you listed into an ASCII file. in that output file, every column has the width from widthList. fileMode tells it how to write to filename: 0 = create a new file and write column headings; 1 = append to an old file and write column headings; 2 = append to an old file but don't write any headings. so basically 0, 1, 2 are the vibes πŸŽ€
  • objName sascii image filename fileMode firstRow numRows firstCol numCols cellSize ?slice? β€” write a block of image data to an ASCII file. in the output file, the data has width cellSize. use the frame slice for 3D image data. 3D? we love a multidimensional moment πŸ¦‹
  • objName flush ?clear? β€” flush any dirty buffers to the disk. if you pass clear, it frees the buffers too. bye bye, buffer πŸ‘‹
  • objName append filename β€” append the current HDU to another FITS file. it's like adding a lil chapter to someone else's book πŸ“–
  • objName checksum update|verify β€” update or verify the checksum keywords in the current HDU. if none exist, update will create them. for verify, the return values are: 1 for valid values, 0 if either keyword (CHECKSUM or DATASUM) is missing, and -1 for invalid values. so 1 = slay, 0 = where is it, -1 = yikes πŸ’€
  • objName info expr expression β€” get info on the result of the arithmetic expression you supply. return value is cDataType numElements {naxesList} where cDataType is the CFITSIO datatype (not fitsTcl's): TDOUBLE, TSTRING, etc; numElements is the number of elements in the result; and naxesList contains the vector dimensions of the result ({1} for a scalar result). an expression that evaluates to a constant (no dependency on the table contents) will be indicated by a negative number of elements. so negative elements = it's giving constant energy 🌟
  • range count rangeStr maxElem β€” count the number of elements (esp. rows) contained within the comma-separated list of ranges in rangeStr (eg, 1-4,5,7-). to support ranges like "7-" which means a range from element 7 through the final element, maxElem is passed with the maximum element number. so you can count from 7 to the end, no biggie ✨
  • fits option ?option? ?value? β€” modify fitsTcl's default behavior. with no options, this returns a list of all the current fitsTcl options and their values. with the option parameter, return the value of that parameter. when both option and value are supplied, set the parameter to the given value. current options: wcsSwap (0). so basically it's the settings menu of your dreams πŸ’–
  • fits version β€” get version numbers for fitsTcl and the underlying cfitsio. it's giving "who am I, really?" but for software πŸ‘‘

✨ AUTHOR ✨

Bryan Irby β€” the icon, the legend, the moment πŸ‘‘


and that's a wrap, bestie! 🎬 this was fits(3tcl) from the Tcl interface to FITS Files, version 2.3 Tcl. no date on this one, but it's timeless anyway πŸ’…βœ¨ mwah πŸ’‹