// change suggested in .99.5 version: Method made public from protected. /// <summary>Given a Header return an appropriate datum.</summary> public static Data DataFactory(Header hdr) { if (ImageHDU.IsHeader(hdr)) { return ImageHDU.ManufactureData(hdr); } else if (RandomGroupsHDU.IsHeader(hdr)) { return RandomGroupsHDU.ManufactureData(hdr); } else if (useAsciiTables && AsciiTableHDU.IsHeader(hdr)) { return AsciiTableHDU.ManufactureData(hdr); } else if (BinaryTableHDU.IsHeader(hdr)) { return BinaryTableHDU.ManufactureData(hdr); } else if (UndefinedHDU.IsHeader(hdr)) { return UndefinedHDU.ManufactureData(hdr); } else { throw new FitsException("Unrecognizable header in dataFactory"); } }
public DateTime? ParseExposure(Header header, out bool isMidPoint, out double? fitsExposure) { if (m_Config.IsTimeStampAndExposure) return ParseExposureCase1(header, out isMidPoint, out fitsExposure); else return ParseExposureCase2(header, out isMidPoint, out fitsExposure); }
/// <summary> /// Create an ascii table header/data unit /// </summary> /// <param name="h">The template specifying the ascii table.</param> /// <param name="d"> The FITS data structure containing the table data.</param> /// <exception cref="FitsException"> FitsException if there was a problem with the header.</exception> public AsciiTableHDU(Header h, Data d) : base((TableData) d) { myHeader = h; data = (AsciiTable) d; myData = d; }
/// <summary> /// Consructor initislizing header,data /// </summary> /// <param name="hdr"></param> /// <param name="datum"></param> public BinaryTableHDU(Header hdr, Data datum) : base((TableData)datum) { myHeader = hdr; myData = datum; table = (BinaryTable) datum; }
private void BuildHeader(Header header, Exposure exposure, Dictionary<string, object> metadata, long maxValue) { // Set BZERO to half of bitness (32768 for 16-bit) header.AddValue("BZERO", 0.5 * maxValue, ""); header.AddValue("BSCALE", (double)1, ""); header.AddValue("DATAMIN", 0.0, ""); header.AddValue("DATAMAX", (double)exposure.MaxDepth, ""); header.AddValue("CBLACK", (double)exposure.PixelMinValue, ""); header.AddValue("CWHITE", (double)exposure.PixelMaxValue, ""); header.AddValue("SWCREATE", "DSImager", ""); if (metadata != null) { foreach (var entry in metadata) { if (entry.Value is int) header.AddValue(entry.Key, (int)entry.Value, ""); if (entry.Value is bool) header.AddValue(entry.Key, (bool)entry.Value, ""); if (entry.Value is double) header.AddValue(entry.Key, (double)entry.Value, ""); if (entry.Value is string) header.AddValue(entry.Key, (string)entry.Value, ""); if (entry.Value is long) header.AddValue(entry.Key, (long)entry.Value, ""); } } }
internal void SaveFitsFrame(string fileName, int width, int height, uint[] framePixels, DateTime timeStamp, float exposureSeconds) { Fits f = new Fits(); object data = SaveImageData(width, height, framePixels); BasicHDU imageHDU = Fits.MakeHDU(data); nom.tam.fits.Header hdr = imageHDU.Header; hdr.AddValue("SIMPLE", "T", null); hdr.AddValue("BITPIX", 32, null); hdr.AddValue("NAXIS", 2, null); hdr.AddValue("NAXIS1", width, null); hdr.AddValue("NAXIS2", height, null); hdr.AddValue("NOTES", m_Note, null); hdr.AddValue("EXPOSURE", exposureSeconds.ToString("0.000", CultureInfo.InvariantCulture), "Exposure, seconds"); hdr.AddValue("DATE-OBS", timeStamp.ToString("yyyy-MM-ddTHH:mm:ss.fff", CultureInfo.InvariantCulture), m_DateObsComment); hdr.AddValue("TANGRAVE", string.Format("{0} v{1}", VersionHelper.AssemblyProduct, VersionHelper.AssemblyFileVersion), "Tangra version"); hdr.AddValue("END", null, null); f.AddHDU(imageHDU); // Write a FITS file. using (BufferedFile bf = new BufferedFile(fileName, FileAccess.ReadWrite, FileShare.ReadWrite)) { f.Write(bf); bf.Flush(); } }
/// <summary>Create an ASCII table given a header</summary> public AsciiTable(Header hdr) { nRows = hdr.GetIntValue("NAXIS2"); nFields = hdr.GetIntValue("TFIELDS"); rowLen = hdr.GetIntValue("NAXIS1"); types = new Type[nFields]; offsets = new int[nFields]; lengths = new int[nFields]; nulls = new String[nFields]; for (int i = 0; i < nFields; i += 1) { offsets[i] = hdr.GetIntValue("TBCOL" + (i + 1)) - 1; String s = hdr.GetStringValue("TFORM" + (i + 1)); if (offsets[i] < 0 || s == null) { throw new FitsException("Invalid Specification for column:" + (i + 1)); } s = s.Trim(); char c = s[0]; s = s.Substring(1); if (s.IndexOf('.') > 0) { s = s.Substring(0, (s.IndexOf('.')) - (0)); } lengths[i] = Int32.Parse(s); switch (c) { case 'A': types[i] = typeof(String); break; case 'I': if (lengths[i] > 10) { types[i] = typeof(long); } else { types[i] = typeof(int); } break; case 'F': case 'E': types[i] = typeof(float); break; case 'D': types[i] = typeof(double); break; } nulls[i] = hdr.GetStringValue("TNULL" + (i + 1)); if (nulls[i] != null) { nulls[i] = nulls[i].Trim(); } } }
/// <summary>Check if we can find the length of the data for this header.</summary> /// <returns><CODE>true</CODE> if this HDU has a valid header.</returns> public static new bool IsHeader(Header hdr) { if(hdr.GetStringValue("XTENSION") != null && hdr.GetIntValue("NAXIS", - 1) >= 0) { return true; } return false; }
internal static void SaveDarkOrFlatFrame(string fileName, int width, int height, string notes, float[,] averagedData, float exposureSeconds, int numFrames) { Fits f = new Fits(); object data = SaveImageData(width, height, averagedData); BasicHDU imageHDU = Fits.MakeHDU(data); nom.tam.fits.Header hdr = imageHDU.Header; hdr.AddValue("SIMPLE", "T", null); hdr.AddValue("BITPIX", -32 /* Floating Point Data*/, null); hdr.AddValue("NAXIS", 2, null); hdr.AddValue("NAXIS1", width, null); hdr.AddValue("NAXIS2", height, null); if (notes.Length > HeaderCard.MAX_VALUE_LENGTH) { notes = notes.Substring(0, HeaderCard.MAX_VALUE_LENGTH); } hdr.AddValue("NOTES", notes, null); if (exposureSeconds > 0) { hdr.AddValue("EXPOSURE", exposureSeconds.ToString("0.000", CultureInfo.InvariantCulture), null); hdr.AddValue("EXPTIME", exposureSeconds.ToString("0.000", CultureInfo.InvariantCulture), null); } hdr.AddValue("SNAPSHOT", numFrames.ToString(), null); hdr.AddValue("TANGRAVE", string.Format("{0} v{1}", VersionHelper.AssemblyProduct, VersionHelper.AssemblyFileVersion), null); if (TangraConfig.Settings.Generic.ReverseGammaCorrection) { hdr.AddValue("TANGAMMA", TangraConfig.Settings.Photometry.EncodingGamma.ToString("0.0000", CultureInfo.InvariantCulture), null); } if (TangraConfig.Settings.Generic.ReverseCameraResponse) { hdr.AddValue("TANCMRSP", ((int)TangraConfig.Settings.Photometry.KnownCameraResponse).ToString(CultureInfo.InvariantCulture), null); } f.AddHDU(imageHDU); // Write a FITS file. using (BufferedFile bf = new BufferedFile(fileName, FileAccess.ReadWrite, FileShare.ReadWrite)) { f.Write(bf); bf.Flush(); } }
/// <summary> /// Create an UndefinedData object using the specified header. /// </summary> /// <param name="h"></param> public UndefinedData(Header h) { int size = 1; for (int i = 0; i < h.GetIntValue("NAXIS"); i += 1) { size *= h.GetIntValue("NAXIS" + (i + 1)); } size += h.GetIntValue("PCOUNT"); if (h.GetIntValue("GCOUNT") > 1) { size *= h.GetIntValue("GCOUNT"); } size *= System.Math.Abs(h.GetIntValue("BITPIX") / 8); data = new byte[size]; byteSize = size; }
private DateTime? ParseExposureCase1(Header header, out bool isMidPoint, out double? fitsExposure) { isMidPoint = true; fitsExposure = null; var timeStampCard = header.FindCard(m_Config.TimeStampHeader); var exposureCard = header.FindCard(m_Config.ExposureHeader); if (timeStampCard != null && exposureCard != null) { double parsedExposure; if (double.TryParse(exposureCard.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out parsedExposure)) fitsExposure = ConvertExposureInSeconds(parsedExposure); DateTime parsedTimeStamp; if (DateTime.TryParseExact(timeStampCard.Value, m_Config.TimeStampFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out parsedTimeStamp)) { switch (m_Config.TimeStampType) { case TangraConfig.TimeStampType.StartExposure: if (fitsExposure != null) { isMidPoint = true; return parsedTimeStamp.AddSeconds(0.5*parsedExposure); } else return parsedTimeStamp; case TangraConfig.TimeStampType.MidExposure: isMidPoint = true; return parsedTimeStamp; case TangraConfig.TimeStampType.EndExposure: if (fitsExposure != null) { isMidPoint = true; return parsedTimeStamp.AddSeconds(-0.5*parsedExposure); } else return parsedTimeStamp; } } } return null; }
internal void SaveFitsFrame(string fileName, Header header, int width, int height, object data) { Fits f = new Fits(); BasicHDU imageHDU = Fits.MakeHDU(data); nom.tam.fits.Header hdr = imageHDU.Header; hdr.AddValue("SIMPLE", "T", null); hdr.AddValue("BZERO", 0, null); hdr.AddValue("BSCALE", 1, null); hdr.AddValue("NAXIS", 2, null); hdr.AddValue("NAXIS1", width, null); hdr.AddValue("NAXIS2", height, null); string[] RESERVED_KEYS = new string[] { "SIMPLE", "NAXIS", "NAXIS1", "NAXIS2", "BZERO", "BSCALE", "END" }; var cursor = header.GetCursor(); while (cursor.MoveNext()) { HeaderCard card = header.FindCard((string)cursor.Key); if (card != null && !string.IsNullOrWhiteSpace(card.Key) && !RESERVED_KEYS.Contains(card.Key)) { hdr.AddValue(card.Key, card.Value, card.Comment); } } hdr.AddValue("NOTES", m_Note, null); hdr.AddValue("TANGRAVE", string.Format("{0} v{1}", VersionHelper.AssemblyProduct, VersionHelper.AssemblyFileVersion), "Tangra version"); hdr.AddValue("END", null, null); f.AddHDU(imageHDU); // Write a FITS file. using (BufferedFile bf = new BufferedFile(fileName, FileAccess.ReadWrite, FileShare.ReadWrite)) { f.Write(bf); bf.Flush(); } }
/// <summary>Create FITS data object corresponding to a given header.</summary> public static Data ManufactureData(Header hdr) { int gcount = hdr.GetIntValue("GCOUNT", - 1); int pcount = hdr.GetIntValue("PCOUNT", - 1); if (!hdr.GetBooleanValue("GROUPS") || hdr.GetIntValue("NAXIS1", - 1) != 0 || gcount < 0 || pcount < 0 || hdr.GetIntValue("NAXIS") < 2) { throw new FitsException("Invalid Random Groups Parameters"); } // Allocate the object. Object[][] dataArray; if (gcount > 0) { dataArray = new Object[gcount][]; for (int i = 0; i < gcount; i++) { dataArray[i] = new Object[2]; } } else { dataArray = new Object[0][]; } Object[] sampleRow = GenerateSampleRow(hdr); for (int i = 0; i < gcount; i += 1) { ((Object[][]) dataArray)[i][0] = ((Object[]) ArrayFuncs.DeepClone(sampleRow))[0]; ((Object[][]) dataArray)[i][1] = ((Object[]) ArrayFuncs.DeepClone(sampleRow))[1]; } return new RandomGroupsData(dataArray); }
/// <summary>Is this a random groups header?</summary> /// <param name="myHeader">The header to be tested.</param> public static new bool IsHeader(Header hdr) { if (hdr.GetBooleanValue("SIMPLE")) { return hdr.GetBooleanValue("GROUPS"); } String s = hdr.GetStringValue("XTENSION"); if (s.Trim().Equals("IMAGE")) { return hdr.GetBooleanValue("GROUPS"); } return false; }
internal override void FillHeader(Header h) { //int[] dims = ArrayFuncs.GetDimensions(dataArray); int[] dims = ArrayFuncs.GetDimensions(dataArray.GetValue(0)); //if (dataArray.Length <= 0 || dataArray[0].Length != 2) if(dims.Length != 2) { throw new FitsException("Data not conformable to Random Groups"); } int gcount = dataArray.Length; //Object paraSamp = dataArray[0][0]; //Object dataSamp = dataArray[0][1]; Object paraSamp = ((Array)dataArray.GetValue(0)).GetValue(0); Object dataSamp = ((Array)dataArray.GetValue(0)).GetValue(1); Type pbase = ArrayFuncs.GetBaseClass(paraSamp); Type dbase = ArrayFuncs.GetBaseClass(dataSamp); if (pbase != dbase) { throw new FitsException("Data and parameters do not agree in type for random group"); } int[] pdims = ArrayFuncs.GetDimensions(paraSamp); int[] ddims = ArrayFuncs.GetDimensions(dataSamp); if (pdims.Length != 1) { throw new FitsException("Parameters are not 1 d array for random groups"); } // Got the information we need to build the header. h.Simple = true; if (dbase == typeof(byte)) { h.Bitpix = 8; } else if (dbase == typeof(short)) { h.Bitpix = 16; } else if (dbase == typeof(int)) { h.Bitpix = 32; } else if (dbase == typeof(long)) { // Non-standard h.Bitpix = 64; } else if (dbase == typeof(float)) { h.Bitpix = - 32; } else if (dbase == typeof(double)) { h.Bitpix = - 64; } else { throw new FitsException("Data type:" + dbase + " not supported for random groups"); } h.Naxes = ddims.Length + 1; h.AddValue("NAXIS1", 0, ""); for (int i = 2; i <= ddims.Length + 1; i += 1) { h.AddValue("NAXIS" + i, ddims[i - 2], ""); } h.AddValue("GROUPS", true, ""); h.AddValue("GCOUNT", dataArray.Length, ""); h.AddValue("PCOUNT", pdims[0], ""); }
/// <summary> /// Create a UndefinedData object to correspond to the header description. /// </summary> /// <param name="hdr"></param> /// <returns></returns> public static Data ManufactureData(Header hdr) { return new UndefinedData(hdr); }
/// <summary> Update the header to reflect the details of a given column.</summary> internal void FillForColumn(Header h, int col, Cursor cursor) { String tform; // .99.1 changes: new method for condition check if (IsVarCol(col)) { if (IsLongVary(col)) { tform = "1Q"; } else { tform = "1P"; } } else { tform = "" + sizes[col]; } if (bases[col] == typeof(int)) { tform += "J"; } //else if (bases[col] == typeof(short) || bases[col] == typeof(char)) else if (bases[col] == typeof(short))// || bases[col] == typeof(char)) { tform += "I"; } else if (bases[col] == typeof(byte)) { tform += "B"; } else if (bases[col] == typeof(float)) { tform += "E"; } else if (bases[col] == typeof(double)) { tform += "D"; } else if (bases[col] == typeof(long)) { tform += "K"; } else if (bases[col] == typeof(bool)) { tform += "L"; } else if (bases[col] == typeof(char) || bases[col] == typeof(String)) { tform += "A"; } else { throw new FitsException("Invalid column data class:" + bases[col]); } String key = "TFORM" + (col + 1); cursor.Add(key, new HeaderCard(key, tform, null)); // .99.1 changes: new method for condition check if (dimens[col].Length > 0 && ((!IsVarCol(col)))) { System.Text.StringBuilder tdim = new System.Text.StringBuilder(); char comma = '('; for (int i = dimens[col].Length - 1; i >= 0; i -= 1) { tdim.Append(comma); tdim.Append(dimens[col][i]); comma = ','; } tdim.Append(')'); key = "TDIM" + (col + 1); cursor.Add(key, new HeaderCard(key, new String(tdim.ToString().ToCharArray()), null)); } }
/// <summary>Create a binary table from given header information.</summary> /// <param name="myHeader">header describing what the binary table should look like.</param> public BinaryTable(Header myHeader) { int heapSize = myHeader.GetIntValue("PCOUNT"); heapOffset = myHeader.GetIntValue("THEAP"); // .99.1 changes: changed the sequence of code lines. int rwsz = myHeader.GetIntValue("NAXIS1"); nRow = myHeader.GetIntValue("NAXIS2"); // Subtract out the size of the regular table from // the heap offset. if (heapOffset > 0) { heapOffset -= nRow * rwsz; } if (heapOffset < 0 || heapOffset > heapSize) { throw new FitsException("Inconsistent THEAP and PCOUNT"); } heap = new FitsHeap(heapSize - heapOffset); nCol = myHeader.GetIntValue("TFIELDS"); rowLen = 0; ExtendArrays(nCol); for (int col = 0; col < nCol; col += 1) { rowLen += ProcessCol(myHeader, col); } // .99.1 changes: Added to replace new value of NAXIS1 keyword. HeaderCard card = myHeader.FindCard("NAXIS1"); card.Value = rowLen.ToString(); myHeader.UpdateLine("NAXIS1", card); }
/// <summary>Make a header point to the given object.</summary> /// <param name="odata">The random groups data the header should describe.</param> internal static Header ManufactureHeader(Data d) { if (d == null) { throw new FitsException("Attempt to create null Random Groups data"); } Header h = new Header(); d.FillHeader(h); return h; }
// change suggested in .99.1 version: Method added. /// <summary> /// Overwrite the lines in the header. /// Add the new PHDU header to the current one. If keywords appear /// twice, the new value and comment overwrite the current contents. /// </summary> /// <param name="newHdr">the list of new header data lines to replace the current ones.</param> public void UpdateLines(Header newHdr) { Cursor j = newHdr.GetCursor(); while (j.MoveNext()) { HeaderCard nextHCard = (HeaderCard)j.Current; // updateLine() doesn't work with COMMENTs because // this would allow only one COMMENT in total in each header if( nextHCard.Key.StartsWith("COMMENT") ) { InsertComment(nextHCard.Comment, cards.Count); } else { UpdateLine(nextHCard.Key, nextHCard); } } }
internal void SaveFitsFrame(int frameNo, string fileName, int width, int height, uint[] framePixels, DateTime timeStamp, float exposureSeconds) { Fits f = new Fits(); object data = m_ExportAs8BitFloat ? (object)SaveNormalizedFloatImageData(width, height, framePixels) : (object)SaveImageData(width, height, framePixels); BasicHDU imageHDU = Fits.MakeHDU(data); nom.tam.fits.Header hdr = imageHDU.Header; hdr.AddValue("SIMPLE", "T", null); hdr.AddValue("BITPIX", m_ExportAs8BitFloat ? -32 : 32, null); hdr.AddValue("BZERO", 0, null); hdr.AddValue("BSCALE", 1, null); hdr.AddValue("NAXIS", 2, null); hdr.AddValue("NAXIS1", width, null); hdr.AddValue("NAXIS2", height, null); hdr.AddValue("EXPOSURE", exposureSeconds.ToString("0.000", CultureInfo.InvariantCulture), "Exposure, seconds"); hdr.AddValue("DATE-OBS", timeStamp.ToString("yyyy-MM-ddTHH:mm:ss.fff", CultureInfo.InvariantCulture), m_DateObsComment); hdr.AddValue("CAMERA", m_VideoCamera, "Video camera model (observer specified)"); hdr.AddValue("FILENAME", m_VideoController.FileName, null); hdr.AddValue("FRAMENO", frameNo, null); if (m_VideoFormat == VideoFileFormat.AAV || m_VideoFormat == VideoFileFormat.AAV2) { hdr.AddValue("NOTES", "No instrumental delay has been applied to DATE-OBS.", null); if (m_ExportAs8BitFloat) { hdr.AddValue("VIDEOFMT", m_NativeFormat, "Native analogue video format"); if (m_IntegrationRate > 0) { hdr.AddValue("INTGRRTE", m_IntegrationRate.ToString(), "Integration rate in video frames"); } } } else { hdr.AddValue("NOTES", string.Format("Converted from {0} file.", m_VideoFormat), null); } foreach (var kvp in m_AdditionalFileHeaders) { hdr.AddValue(kvp.Key, kvp.Value.Item1, kvp.Value.Item2); } hdr.AddValue("TANGRAVE", string.Format("{0} v{1}", VersionHelper.AssemblyProduct, VersionHelper.AssemblyFileVersion), "Tangra version"); hdr.AddValue("END", null, null); f.AddHDU(imageHDU); // Write a FITS file. using (BufferedFile bf = new BufferedFile(fileName, FileAccess.ReadWrite, FileShare.ReadWrite)) { f.Write(bf); bf.Flush(); } }
protected internal virtual ArrayDesc ParseHeader(Header h) { int bitpix; // int type; int ndim; int[] dims; int i; //Object dataArray; Type baseClass; int gCount = h.GetIntValue("GCOUNT", 1); int pCount = h.GetIntValue("PCOUNT", 0); if (gCount > 1 || pCount != 0) { throw new FitsException("Group data treated as images"); } bitpix = (int) h.GetIntValue("BITPIX", 0); if (bitpix == 8) { baseClass = Type.GetType("System.Byte"); } else if (bitpix == 16) { baseClass = Type.GetType("System.Int16"); } else if (bitpix == 32) { baseClass = Type.GetType("System.Int32"); } else if (bitpix == 64) { /* This isn't a standard for FITS yet...*/ baseClass = Type.GetType("System.Int64"); } else if (bitpix == - 32) { baseClass = Type.GetType("System.Single"); } else if (bitpix == - 64) { baseClass = Type.GetType("System.Double"); } else { throw new FitsException("Invalid BITPIX:" + bitpix); } ndim = h.GetIntValue("NAXIS", 0); dims = new int[ndim]; // Note that we have to invert the order of the axes // for the FITS file to get the order in the array we // are generating. byteSize = 1; for (i = 0; i < ndim; i += 1) { int cdim = h.GetIntValue("NAXIS" + (i + 1), 0); if (cdim < 0) { throw new FitsException("Invalid array dimension:" + cdim); } byteSize *= cdim; dims[ndim - i - 1] = (int) cdim; } byteSize *= Math.Abs(bitpix) / 8; if (ndim == 0) { byteSize = 0; } return new ArrayDesc(this, dims, baseClass); }
/// <summary>Build an image HDU using the supplied data.</summary> /// <param name="obj">the data used to build the image.</param> /// <exception cref=""> FitsException if there was a problem with the data.</exception> public UndefinedHDU(Header h, Data d) { myData = d; myHeader = h; }
private DateTime? ParseExposureCase2(Header header, out bool isMidPoint, out double? fitsExposure) { throw new NotImplementedException(); }
internal static Object[] GenerateSampleRow(Header h) { int ndim = h.GetIntValue("NAXIS", 0) - 1; int[] dims = new int[ndim]; int bitpix = h.GetIntValue("BITPIX", 0); Type baseClass; switch (bitpix) { case 8: baseClass = typeof(byte); break; case 16: baseClass = typeof(short); break; case 32: baseClass = typeof(int); break; case 64: baseClass = typeof(long); break; case - 32: baseClass = typeof(float); break; case - 64: baseClass = typeof(double); break; default: throw new FitsException("Invalid BITPIX:" + bitpix); } // Note that we have to invert the order of the axes // for the FITS file to get the order in the array we // are generating. Also recall that NAXIS1=0, so that // we have an 'extra' dimension. for (int i = 0; i < ndim; i += 1) { long cdim = h.GetIntValue("NAXIS" + (i + 2), 0); if (cdim < 0) { throw new FitsException("Invalid array dimension:" + cdim); } dims[ndim - i - 1] = (int) cdim; } Object[] sample = new Object[2]; sample[0] = ArrayFuncs.NewInstance(baseClass, h.GetIntValue("PCOUNT")); sample[1] = ArrayFuncs.NewInstance(baseClass, dims); return sample; }
/// <summary>Process one column from a FITS Header.</summary> private int ProcessCol(Header header, int col) { String tform = header.GetStringValue("TFORM" + (col + 1)); // .99 changes if (tform == null) { throw new FitsException("Attempt to process column " + (col + 1) + " but no TFORMn found."); } tform = tform.Trim(); String tdims = header.GetStringValue("TDIM" + (col + 1)); if (tform == null) { throw new FitsException("No TFORM for column:" + col); } if (tdims != null) { tdims = tdims.Trim(); } char type = GetTformType(tform); // .99.1 changes: condition changed if (type == 'P' || type == 'Q') { flags[col] |= COL_VARYING; // .99.1 changes: if (type == 'Q') { flags[col] |= COL_LONGVARY; } type = GetTformVarType(tform); } int size = GetTformLength(tform); // Handle the special size cases. // // Bit arrays if (type == 'X') { size = (size + 7) / 8; flags[col] |= COL_BIT; // Variable length arrays (just a two element array ) } // .99.1 changes: new method for condition check else if (IsVarCol(col)) { size = 2; } int bSize = size; int[] dims = null; // .99.1 changes: new method for condition check // Cannot really handle arbitrary arrays of bits. if (tdims != null && type != 'X' && !IsVarCol(col)) { dims = GetTDims(tdims); } if (dims == null) { // .99.1 change if (size == 1) { dims = new int[0]; } else { dims = new int[] { size }; } } if (type == 'C' || type == 'M') { flags[col] |= COL_COMPLEX; } Type colBase = null; switch (type) { case 'A': colBase = typeof(byte); flags[col] |= COL_STRING; bases[col] = typeof(String); break; case 'L': colBase = typeof(byte); bases[col] = typeof(bool); flags[col] |= COL_BOOLEAN; break; case 'X': case 'B': colBase = typeof(byte); bases[col] = typeof(byte); break; case 'I': colBase = typeof(short); bases[col] = typeof(short); bSize *= 2; break; case 'J': colBase = typeof(int); bases[col] = typeof(int); bSize *= 4; break; case 'K': colBase = typeof(long); bases[col] = typeof(long); bSize *= 8; break; case 'E': case 'C': colBase = typeof(float); bases[col] = typeof(float); bSize *= 4; break; case 'D': case 'M': colBase = typeof(double); bases[col] = typeof(double); bSize *= 8; break; default: throw new FitsException("Invalid type in column:" + col); } // .99.1 changes: new method for condition check if (IsVarCol(col)) { dims = new int[]{nRow, 2}; colBase = typeof(int); bSize = 8; } // .99.1 changes: new method for condition check else if (IsLongVary(col)) { colBase = typeof(long); bSize = 16; } // .99.1 changes: new method for condition check else if (IsComplex(col)) { int[] xdims = new int[dims.Length + 1]; Array.Copy(dims, 0, xdims, 0, dims.Length); xdims[dims.Length] = 2; dims = xdims; } modelRow[col] = ArrayFuncs.NewInstance(colBase, dims); dimens[col] = dims; sizes[col] = size; return bSize; }
//internal Object dataArray; /// <summary>Create an HDU from the given header and data</summary> public RandomGroupsHDU(Header h, Data d) { myHeader = h; myData = d; }
// .99.1 changes: /// <summary> Update the header after a deletion.</summary> public void UpdateAfterDelete(int oldNcol, Header hdr) { hdr.AddValue("NAXIS1", rowLen, "Bytes per row"); }
/// <summary>Fill header with keywords that describe image data.</summary> /// <param name="head">The FITS header</param> /// <exception cref="FitsException"> FitsException if the object does not contain valid image data.</exception> internal override void FillHeader(Header head) { if (dataArray == null) { head.NullImage(); return ; } Type classname = ArrayFuncs.GetBaseClass(dataArray); int[] dimens = ArrayFuncs.GetDimensions(dataArray); if (dimens == null || dimens.Length == 0) { throw new FitsException("Image data object not array. "); } int bitpix; // Changed from classname[dimens.Length] to classname[classname.IndexOf(".") + 1] switch (classname.ToString()) { case "System.Byte": bitpix = 8; break; case "System.Int16": bitpix = 16; break; case "System.Int32": bitpix = 32; break; case "System.Int64": bitpix = 64; break; case "System.Single": bitpix = - 32; break; case "System.Double": bitpix = - 64; break; default: throw new FitsException("Invalid Object Type for FITS data:" + classname.ToString()); } // if this is neither a primary header nor an image extension, // make it a primary header head.Simple = true; head.Bitpix = bitpix; head.Naxes = dimens.Length; for (int i = 1; i <= dimens.Length; i += 1) { if (dimens[i - 1] == - 1) { throw new FitsException("Unfilled array for dimension: " + i); } head.SetNaxis(i, dimens[dimens.Length - i]); } // suggested in .97 version: EXTEND keyword added before PCOUNT and GCOUNT. head.AddValue("EXTEND", true, "Extension permitted"); // Just in case! head.AddValue("PCOUNT", 0, "No extra parameters"); head.AddValue("GCOUNT", 1, "One group"); }
/// <summary>Create a header that describes the given /// image data. /// </summary> /// <param name="o">The image to be described. /// </param> /// <exception cref=""> FitsException if the object does not contain /// valid image data. /// /// </exception> public static Header ManufactureHeader(Data d) { Header h = new Header(); d.FillHeader(h); return h; }
/// <summary>Create an array from a header description. /// This is typically how data will be created when reading /// FITS data from a file where the header is read first. /// This creates an empty array.</summary> /// <param name="h">header to be used as a template.</param> /// <exception cref="FitsException"> FitsException if there was a problem with the header description.</exception> public ImageData(Header h) { dataDescription = ParseHeader(h); }
/// <summary> Update a FITS header to reflect the current state of the data.</summary> internal override void FillHeader(Header h) { try { h.Xtension = "BINTABLE"; h.Bitpix = 8; h.Naxes = 2; h.SetNaxis(1, rowLen); h.SetNaxis(2, nRow); h.AddValue("PCOUNT", heap.Size, null); h.AddValue("GCOUNT", 1, null); Cursor c = h.GetCursor(); c.Key = "GCOUNT"; c.MoveNext(); c.Add("TFIELDS", new HeaderCard("TFIELDS", modelRow.Length, null)); for(int i = 0; i < modelRow.Length; i += 1) { if(i > 0) { h.PositionAfterIndex("TFORM", i); } FillForColumn(h, i, c); } } catch(HeaderCardException) { Console.Error.WriteLine("Impossible exception"); } }
/// <summary>Create a header by reading the information from the input stream.</summary> /// <param name="dis">The input stream to read the data from.</param> /// <returns> <CODE>null</CODE> if there was a problem with the header; /// otherwise return the header read from the input stream.</returns> public static Header ReadHeader(ArrayDataIO dis) { Header myHeader = new Header(); try { myHeader.Read(dis); } catch(EndOfStreamException) { // An EOF exception is thrown only if the EOF was detected // when reading the first card. In this case we want // to return a null. return null; } return myHeader; }
/// <summary> Update the header to reflect information about a given column. /// This routine tries to ensure that the Header is organized by column.</summary> internal void PointToColumn(int col, Header hdr) { Cursor c = hdr.GetCursor(); if(col > 0) { hdr.PositionAfterIndex("TFORM", col); } FillForColumn(hdr, col, c); }