# Kislovodsk Mountain Astronomical Station Data Formats All formats are plain text. The following functions in `io.py` read these files: | Format | Contents | Reader | | --- | --- | --- | | `.dat` | Coronal intensity as a function of position angle | `open_corona` | | `.abp` | Object masks in pixel coordinates | `open_abp` | | `.abz` | Row-wise interval encoding of pixel masks | No reader in the supplied `io.py` | | `.bp`, `.bp2` | Tables of object parameters | `open_bp` | | `.grp` | Sunspot groups, individual spots, and umbrae | `open_grp` | | `.cnt` | Object contours in heliographic coordinates | `open_cnt` | | `.prb` | Prominence parameter tables | `open_bp` | | `.pral` | Prominence masks in polar coordinates | `open_pral` | | `.pbz` | Row-wise interval encoding of prominence pixel masks | No reader in the supplied `io.py` | Fields are separated by variable amounts of whitespace, except for BP and GRP column names, which are separated by `|`. In the layouts below, ellipses indicate repeated data and square brackets indicate optional fields. Line boundaries must be preserved in ABP and CNT files: each object occupies exactly two lines. ## DAT — Coronal Intensity Annual files for the red line at **6374 Å** and the green line at **5303 Å** use naming patterns `r%Y*.dat` and `g*%Y.dat`. The year also occurs after a letter prefix (`r*%Y.dat`). `%Y` denotes a four-digit year. ```text Corona wavelength Kislovodsk YYYY Jan T.U. 0 5 10 ... 350 355 DD HH MM I_0 I_5 I_10 ... I_350 I_355 ... Feb DD HH MM I_0 I_5 I_10 ... I_350 I_355 ... ``` | Element | Contents | | --- | --- | | First line | Wavelength in angstroms | | Second line | Observation year | | Line containing `T.U.` | Universal Time label and angular grid | | Measurement line | Day of month, UT hours and minutes, followed by intensities | | Month separator | `Feb`, `Mar`, `Apr`, `May`, `Jun`, `Jul`, `Aug`, `Sep`, `Oct`, `Nov`, `Dec` | The standard grid contains **72 angles from 0° to 355° in 5° steps**, measured clockwise from the solar north pole. Each measurement line contains 75 fields. The header supplies the year and the current block supplies the month; January data begin immediately after the angular grid. Intensities are integers. Missing values are marked with `-`, `x`, `X`, or `?` and are represented as `-1` when read. Dates without observations have no entries. ## ABP — Pixel Masks ```text xc yc R P B0 L0 [auxiliary fields] n_skip [auxiliary fields] N x1 y1 c1 x2 y2 c2 ... xM yM cM ... ``` ### Header | Field | Contents | | --- | --- | | `xc`, `yc` | Integer disk-center coordinates, in pixels | | `R` | Integer disk radius, in pixels | | `P` | Disk orientation angle, in degrees | | `B0`, `L0` | Heliographic latitude and longitude of the disk center, in degrees | | `n_skip` | Number of additional lines preceding the object-count line | | `N` | Number of objects | When `n_skip = 0`, the `N` line immediately follows the second header line. ### Object Block The first line contains integer parameters: | Position | Contents | | --- | --- | | 1 | Object number within the file | | 2 | Mask area in pixels (`area_px`) | | 3 | Group number | | 4–5 | Auxiliary fields | | 6 | Object identifier component | | 7 | Additional identifier component; for sunspots, also an umbra flag: `0` means absent, a nonzero value means present | The second line lists **triplets `x y c`**: pixel coordinates followed by an additional integer code. The mask lists the object's pixels rather than tracing its boundary. The number of triplets equals `area_px`. A file containing `N` objects has `3 + n_skip + 2N` lines. ## ABZ — Row-Wise Pixel Masks ABZ stores filament masks as horizontal pixel intervals. It is a plain-text representation of mask geometry, with a variable number of lines per object. The layout below is verified for filament files with the second header line `0 0`: ```text xc yc R P B0 L0 0 0 N object_number area_px group_number auxiliary component subcomponent x_lo x_hi y_min y_max y_min x_start -x_end [x_start -x_end ...] ... y_max x_start -x_end [x_start -x_end ...] ... ``` The first line uses the same disk geometry and angular parameters as ABP. The third line gives the number of objects. ### Object Header Each object header contains ten integers: | Position | Contents | Corresponding ABP field | | --- | --- | --- | | 1 | Object number | 1 | | 2 | Mask area in pixels | 2 | | 3 | Group number | 3 | | 4 | Auxiliary value | 4 | | 5 | Object identifier component | 6 | | 6 | Additional identifier component | 7 | | 7–8 | Horizontal bounding limits `x_lo`, `x_hi` | — | | 9–10 | First and last occupied image rows, `y_min`, `y_max` | — | ABP field 5 is omitted from the ABZ object header. In the verified layout, `x_lo` is one pixel below the minimum occupied x coordinate and `x_hi` is one pixel above the maximum. The y bounds are inclusive occupied-row coordinates. ### Mask Rows The header is followed by `y_max − y_min + 1` image-row records, in increasing y order. Each begins with y and then lists pairs `x_start -x_end`. The minus sign marks an interval end; it does not indicate a negative image coordinate. Both interval endpoints are included. Multiple pairs on one line represent separate occupied segments at the same y. ```text 100 20 -23 30 -32 ``` This row contains pixels `(20, 100)` through `(23, 100)` and `(30, 100)` through `(32, 100)`: seven pixels in total. The sum of interval lengths, `x_end − x_start + 1`, equals `area_px`. After the final y row, the next line is the next object header. For this layout, the total line count is `3 + sum(1 + y_max − y_min + 1)` over all objects. ABZ stores pixel membership without the third per-pixel code `c` used in ABP. Decoding ABZ therefore reconstructs the mask coordinates, not all fields of an ABP file. ## BP — Object Parameters ```text column_1 | column_2 | ... | ... Total ... ``` The descriptive header includes the original path, date and time, processing parameters (`parameters:`), and observer (`Observer:`). Geometric parameters use the following labels: | Label | Contents | | --- | --- | | `R`, `xc`, `yc` | Disk radius and center coordinates, in pixels | | `P` | Disk orientation angle, in degrees | | `D` | Disk-center latitude (`B0`), in degrees | | `L0` | Disk-center longitude, in degrees | | `kol` | Number of objects | The table columns depend on the object type. Filament tables use the following columns: | Columns | Contents | | --- | --- | | `qmx`, `fimx` | Latitude and longitude at the maximum-longitude point, in degrees | | `qmn`, `fimn` | Latitude and longitude at the minimum-longitude point, in degrees | | `Int` | Intensity indicator | | `S` | Object area | The latitude values belong to the longitude-extreme points; they are not independent latitude extrema. Longitude comparisons must account for the 0°/360° boundary. The `um` label denotes a sunspot umbra. The footer begins with `Total` and contains summary quantities. Text fields and totals allow a comma as the decimal separator. ### BP2 — Object Tables with Additional-Layer Statistics BP2 extends an object parameter table with statistics measured in an additional, spatially aligned data layer within each object's mask. In coronal-hole processing, coronal-hole masks are overlaid on SDO magnetograms to characterize the magnetic field inside the holes. The mask defines the measurement region; the additional layer supplies the values being measured. For a magnetic-field layer, the extra quantities include field extrema and averages, magnetic-flux measures, and separate statistics for positive and negative polarities. The field component (LOS or radial), units, and projection corrections depend on the source layer and processing configuration. BP2 uses the BP structure: an observation header, a geometry header, a `|`-separated column header, whitespace-separated numeric records, and a footer beginning with `Total`. The filename recorded inside the header can retain the `.bp` extension. The geometry header also includes an `EW` field. The column sequence is: ```text q | fi | L | r/R | Smhm | Spx | dq | dfi | Int | cntr | mn | mx | al | flux | lenght | BP2 | maxBP2 | n_px | qn | fin | ar_n | flx_n | p_px | qp | fip | ar_p | flx_p | bndB | gradB ``` The line wrapping above is for display only; the actual column header occupies one line. | Columns | Contents | | --- | --- | | `q`, `fi`, `L` | Latitude, longitude offset from the central meridian, and Carrington longitude, degrees | | `r/R` | Normalized projected disk-center distance | | `Smhm`, `Spx` | Corrected area in MSH and mask area in pixels | | `dq`, `dfi` | Angular extents in latitude and longitude, degrees | | `Int`, `cntr` | Intensity and contrast indicators | | `mn`, `mx`, `al`, `flux` | Additional-layer statistics; interpreted for a magnetic layer as minimum, maximum, and mean field, and magnetic flux | | `n_px`, `p_px` | Pixel counts for the negative and positive subsets | | `qn`, `fin`, `qp`, `fip` | Coordinates associated with the negative and positive subsets | | `ar_n`, `ar_p`, `flx_n`, `flx_p` | Areas and fluxes associated with the negative and positive subsets | | `lenght`, `BP2`, `maxBP2`, `bndB`, `gradB` | Additional diagnostics retained under their original column names | Scientific notation is accepted in numeric records. Keep the spelling `lenght` as written in the file. The magnetic interpretation above describes the intended use of the additional-layer statistics. Exact definitions, including signed versus unsigned quantities, averaging weights, and flux normalization, belong to the generating code; they are not specified by the reader. `BP2` and `maxBP2` are retained without assigning an unverified physical meaning. Count actual data records up to `Total`; the geometry header's `kol` value is not a guaranteed record count. Do not infer missing objects or create extra rows from that value. ## GRP — Sunspot Groups and Individual Spots GRP files contain group summaries and measurements of individual spots and their umbrae from one observation. ```text YYYY/MM/DD HH:MM parameters: ... Observer: ... R: ... xc: ... yc: ... D: ... L0: ... P: ... (...) N | q | fi | L | r/R | Smhm | Spx | dq | dfi | Int | cntr | Perim | Ind Ngr: ... Nsp= ... fi= ... (...) q= ... umb: ... Wg: ... pxl= ... S= ... Smx= ... r= ... (...) qs= ... fis= ... um ... Total groups: ... Spot: ... S: ... umb: ... W: ... -N- groups: ... Spot: ... S: ... umb: ... WN: ... -S- groups: ... Spot: ... S: ... umb: ... WS: ... ``` ### Header and Group Summaries The first line gives the observation date and time, processing parameters, and observer. The second gives the disk radius `R` and center `xc`, `yc` in pixels, disk-center latitude `D` and longitude `L0` in degrees, and two orientation values after `P:`. The reader stores the unparenthesized orientation value as `P_d` and the parenthesized value as `P`. Each group begins with two summary lines: | Label | Contents | | --- | --- | | `Ngr` | Group number | | `Nsp` | Number of spots | | `fi`, `q` | Longitude-offset and latitude ranges; parenthesized longitudes are Carrington longitudes | | `umb` | Number of umbrae | | `Wg` | Reported group Wolf number | | `pxl` | Total spot area in pixels | | `S` | Total corrected spot area in MSH | | `Smx` | Largest individual spot area in MSH | | `r` | Range of normalized disk-center distances and a parenthesized group value | | `qs`, `fis` | Group latitude and longitude offset from the central meridian, in degrees | ### Individual Measurements Column boundaries are defined by the positions of `|` in the table header. Measurement rows contain aligned values without these separators. | Column | Contents | | --- | --- | | `N` | Spot number within the current group, or `um` followed by the umbra number | | `q` | Heliographic latitude, degrees | | `fi` | Longitude offset from the central meridian, degrees | | `L` | Carrington longitude, degrees | | `r/R` | Projected disk-center distance divided by the apparent solar radius | | `Smhm` | Corrected area in millionths of a solar hemisphere (MSH) | | `Spx` | Mask area in pixels | | `dq`, `dfi` | Angular extents in latitude and longitude, degrees | | `Int` | Intensity indicator | | `cntr` | Contrast indicator | | `Perim` | Perimeter indicator | | `Ind` | Spot index within the group; umbra rows carry their parent spot index | An integer in the first column starts a spot record. Following `um` rows describe umbrae belonging to that spot; their numbers distinguish multiple umbrae within it. Umbrae have separate masks and measurements, but are parts of the parent spots and must not be added again to the total spot area. The footer provides full-disk totals (`Total`) and northern (`-N-`) and southern (`-S-`) hemisphere totals. ## CNT — Heliographic Contours ```text P B0 L0 [auxiliary fields] B1 L1 B2 L2 ... BK LK ... ``` Fields 4–6 of the first line contain `P`, `B0`, and `L0`, in degrees. After the first two lines, each contour occupies two lines: its description and its coordinates. **Coordinates are stored as latitude `B` followed by longitude `L`**, in degrees. Fractional values use a decimal point. The number of coordinate values is even, and their order defines the traversal of the contour. A file containing `N` contours has `2 + 2N` lines. ## Prominence Formats — PRB, PRAL, and PBZ These formats describe prominence parameters and masks from the same observation. PRB is a BP-style table, PRAL stores polar point coordinates, and PBZ stores compressed Cartesian pixel coordinates. ### PRB — Prominence Parameters ```text R: ... xc: ... yc: ... P: ... D: ... L0: ... kol: ... latitude | lenght | height | Ints | ars2/10 | ... ... ``` | Column | Contents | | --- | --- | | `latitude` | Signed reported latitude with a limb suffix: `W` for west or `E` for east | | `lenght` | Angular extent along the limb, degrees | | `height` | Radial extent of the object, arcseconds | | `Ints` | Intensity class | | `ars2/10` | Projected angular area divided by ten, in square arcseconds; multiply the stored value by ten to recover the area in arcsec² | `latitude` is a text field, for example `61W` or `-44E`. Preserve the header spelling `lenght`. Empty trailing column labels are padding, not additional measurements. The table is readable with `open_bp`; no separate `open_prb` function is required. Here, `height` describes radial thickness, not necessarily the top's elevation above the limb: a detached prominence can have a nonzero lower height. PRAL retains both radial limits. ### PRAL — Polar Point Masks ```text xc yc R P B0 L0 N object_number area_px auxiliary_1 auxiliary_2 r_min r_max a_min a_max r1 a1 c1 r2 a2 c2 ... rM aM cM ... ``` Each object occupies two lines. The first contains eight parameters; the second lists one triplet per mask pixel. | Field | Contents | | --- | --- | | `object_number` | File-local object identifier | | `area_px` | Number of mask pixels | | `auxiliary_1`, `auxiliary_2` | Auxiliary values | | `r_min`, `r_max` | Minimum and maximum normalized radial coordinates | | `a_min`, `a_max` | Angular bounds in degrees | | `r`, `a`, `c` | Normalized radius, position angle in degrees, and an integer pixel code | The radial coordinate is the distance from the disk center divided by `R`; the reference limb is at `r = 1`. Values below one are retained as recorded. The normalized elevation above the reference limb is `r − 1`. For the verified zero-rotation geometry (`P = 0`), `a` increases clockwise from the upward image direction. Pixel coordinates are recovered as ```text x = xc + R * r * sin(a) y = yc - R * r * cos(a) ``` Convert degrees to radians before evaluating the trigonometric functions, and round the result to integer pixels. The formula is verified for `P = 0`; a nonzero-P transformation has not been established here. The number of triplets equals `area_px`. A file with `N` objects has `2 + 2N` lines. Header bounds and point coordinates are rounded independently and can differ in their final decimal places. ### PBZ — Cartesian Interval Masks ```text xc yc R P B0 L0 N object_number area_px auxiliary_1 auxiliary_2 x_lo x_hi y_min y_max y_min x_start -x_end [x_start -x_end ...] ... y_max x_start -x_end [x_start -x_end ...] ... ``` PBZ uses the same inclusive interval encoding as ABZ: each row starts with y, followed by positive interval starts and negative interval-end markers. The coordinates are image pixels, not polar coordinates. Each object header has eight integers. The first four match the corresponding PRAL object header. The last four are Cartesian bounds. In the verified layout, `x_lo = min(x) − 1`, `x_hi = max(x) + 1`, and the y limits are the first and last occupied rows. Each header is followed by `y_max − y_min + 1` row records. Their decoded pixel count equals `area_px`. PBZ does not store the per-pixel `c` codes from PRAL. ## Relationships Between Files Match files from the same observation before matching individual records. Pixel masks, parameter tables, and heliographic contours describe different representations of the observed objects. ### GRP–ABP GRP supplies measurements and group summaries; ABP supplies the corresponding pixel masks. Match individual records using the group, spot, and umbra numbers: | Identifier component | GRP | ABP object-parameter position | | --- | --- | --- | | Group number | Current `Ngr` | 3 | | Spot number | Integer in the first column of the parent spot row | 6 | | Umbra number | Number after `um`; zero for the parent spot | 7 | The resulting identifier is `group-spot` for a spot and `group-spot-umbra` for an umbra. Both readers expose this identifier as `id`. Include the observation identity when combining files from different times. GRP `Spx` corresponds to ABP `area_px`. GRP group summaries correspond to collections of ABP objects with the same group number, rather than to additional individual masks. ABP also contains group-level records among the additional header lines. ABP `object_number` is a separate file-local identifier. It is not the spot number in GRP. Record order differs between the two formats, so positional matching is inappropriate. ### ABZ–ABP Match object records by `object_number` within the same observation. ABZ header fields 1–6 correspond to ABP fields 1, 2, 3, 4, 6, and 7. Validate the identifier components and `area_px`, then compare the decoded ABZ pixel set with the ABP `(x, y)` pixel set. The filament pair used to verify this layout contains 40 objects; every decoded ABZ mask matches its ABP mask exactly. This establishes equivalence of pixel membership for that pair, not preservation of ABP pixel codes. ### BP–ABP for Filaments BP supplies filament parameters; ABP supplies their pixel masks. Record order is not a reliable key: a verified pair contains the same 40 objects, but one object appears third in ABP and last in BP. To establish correspondence, transform each mask to heliographic coordinates using the observation geometry, obtain the longitude-extreme points, and compare them with BP `qmx`, `fimx`, `qmn`, and `fimn`. Account for longitude wrapping and coordinate rounding. Require a one-to-one assignment; keep unmatched and ambiguous objects explicitly flagged. Do not compare BP `S` directly with ABP `area_px` as if they were the same quantity: `area_px` is a pixel count. ### CNT–BP CNT supplies heliographic contours; BP supplies object parameters. The supplied CNT reader retains contour-block order but does not expose identifiers from the contour-description lines. The correspondence for this pair of formats has not yet been verified. Before attaching BP parameters to contours, compare their coordinates and establish a one-to-one mapping. Equal record counts alone do not establish positional correspondence. ### PRAL–PBZ–PRB Match PRAL and PBZ using `object_number` within the same observation. Verify equal pixel counts, convert PRAL coordinates to integer image pixels using the appropriate orientation, and compare the resulting pixel sets. For the verified `P = 0` pair, all 24 objects match exactly. PRB has no explicit object identifier. In the inspected set its 24 records follow PRAL/PBZ object order. The rounded angular extents agree with `a_max − a_min`, and the radial extents agree with `r_max − r_min` converted to arcseconds. This is a checked correspondence for that observation, not a universal ordering guarantee. For each new observation, validate PRB correspondence using limb, position, angular extent, radial extent, and area. Keep unmatched or ambiguous records separate rather than assigning them solely by row number. ### Validation and Mapping Records Validate relationships for each observation when combining files. For GRP–ABP, check identifier uniqueness and pixel-area agreement. For ABZ–ABP, check identifiers, area, and decoded pixel membership. For filament parameter tables and geometry, check coordinate agreement and uniqueness of the assignment. Store the mapping separately with the observation identity, source filenames, source record identifiers or row indices, matching method, coordinate residual where applicable, and status (`matched`, `unmatched`, or `ambiguous`). Preserve original record order and identifiers. A nearest candidate alone is not sufficient evidence of a unique match.