modified from suvi code by vhsu

def save(self):
        """ modified from suvi code by vhsu """
        pri_hdu = fits.PrimaryHDU(data=self.thmap)

        # Temporal Information
        date_fmt = '%Y-%m-%dT%H:%M:%S.%f'
        date_beg = self.start_time.strftime(date_fmt)
        date_end = self.end_time.strftime(date_fmt)
        date_now = datetime.utcnow().strftime(date_fmt)
        self.set_fits_header("TIMESYS", self.ref_hdr, pri_hdu)
        pri_hdu.header.append(("DATE-BEG", date_beg, "sun observation start time on sat"))
        pri_hdu.header.append(("DATE-END", date_end, "sun observation end time on sat"))
        pri_hdu.header.append(("DATE", date_now, "file generation time"))
        pri_hdu.header.append(("EXPERT", self.config.expert, "person who labeled image"))
        pri_hdu.header.append(("DATE-LAB", date_now, "date of labeling for the image"))

        # Instrument & Spacecraft State during Observation
        pri_hdu.header.append(("EXPTIME", 1., "[s] effective imaging exposure time"))
        self.set_fits_header("YAW_FLIP", self.ref_hdr, pri_hdu)
        self.set_fits_header("ECLIPSE", self.ref_hdr, pri_hdu)

        # Pointing & Projection
        self.set_fits_header("WCSNAME", self.ref_hdr, pri_hdu)
        self.set_fits_header("CTYPE1", self.ref_hdr, pri_hdu)
        self.set_fits_header("CTYPE2", self.ref_hdr, pri_hdu)
        self.set_fits_header("CUNIT1", self.ref_hdr, pri_hdu)
        self.set_fits_header("CUNIT2", self.ref_hdr, pri_hdu)
        self.set_fits_header("PC1_1", self.ref_hdr, pri_hdu)
        self.set_fits_header("PC1_2", self.ref_hdr, pri_hdu)
        self.set_fits_header("PC2_1", self.ref_hdr, pri_hdu)
        self.set_fits_header("PC2_2", self.ref_hdr, pri_hdu)
        self.set_fits_header("CDELT1", self.ref_hdr, pri_hdu)
        self.set_fits_header("CDELT2", self.ref_hdr, pri_hdu)
        self.set_fits_header("CRVAL1", self.ref_hdr, pri_hdu)
        self.set_fits_header("CRVAL2", self.ref_hdr, pri_hdu)
        self.set_fits_header("CRPIX1", self.ref_hdr, pri_hdu)
        self.set_fits_header("CRPIX2", self.ref_hdr, pri_hdu)
        self.set_fits_header("DIAM_SUN", self.ref_hdr, pri_hdu)
        self.set_fits_header("LONPOLE", self.ref_hdr, pri_hdu)
        self.set_fits_header("CROTA", self.ref_hdr, pri_hdu)
        self.set_fits_header("SOLAR_B0", self.ref_hdr, pri_hdu)

        # File Provenance
        pri_hdu.header.append(("TITLE", "Expert Labeled Thematic Map Image", "image title"))
        pri_hdu.header.append(("MAP_MTHD", "human", "thematic map classifier method"))
        try:
            # Add COMMENT cards
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 1,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 2, ("COMMENT", 'USING SUVI THEMATIC MAP FILES'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 3,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 4,
                                  ("COMMENT", 'Map labels are described in the FITS extension.'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 5, ("COMMENT", 'Example:'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 6, ("COMMENT", 'from astropy.io import fits as pyfits'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 7, ("COMMENT", 'img = pyfits.open(<filename>)'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 8, ("COMMENT", 'map_labels = img[1].data'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 9,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 10, ("COMMENT", 'TEMPORAL INFORMATION'))
            pri_hdu.header.insert(pri_hdu.header.index("TITLE") + 11,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("DATE") + 1,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("DATE") + 2,
                                  ("COMMENT", 'INSTRUMENT & SPACECRAFT STATE DURING OBSERVATION'))
            pri_hdu.header.insert(pri_hdu.header.index("DATE") + 3,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("ECLIPSE") + 1,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("ECLIPSE") + 2, ("COMMENT", 'POINTING & PROJECTION'))
            pri_hdu.header.insert(pri_hdu.header.index("ECLIPSE") + 3,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("SOLAR_B0") + 1,
                                  ("COMMENT", '------------------------------------------------------------------------'))
            pri_hdu.header.insert(pri_hdu.header.index("SOLAR_B0") + 2, ("COMMENT", 'FILE PROVENANCE'))
            pri_hdu.header.insert(pri_hdu.header.index("SOLAR_B0") + 3,
                                  ("COMMENT", '------------------------------------------------------------------------'))
        except:
            print("This thematic map may be degraded and missing many keywords.")

        # Thematic map feature list (Secondary HDU extension)
        map_val = []
        map_label = []
        for key, value in self.config.solar_class_index.items(): #sorted(SOLAR_CLASS_INDEX.items(), key=lambda p: (lambda k, v: (v, k))):
            map_label.append(key)
            map_val.append(value)
        c1 = fits.Column(name="Thematic Map Value", format="B", array=np.array(map_val))
        c2 = fits.Column(name="Feature Name", format="22A", array=np.array(map_label))
        bintbl_hdr = fits.Header([("XTENSION", "BINTABLE")])
        sec_hdu = fits.BinTableHDU.from_columns([c1, c2], header=bintbl_hdr)

        # Output thematic map as the primary HDU and the list of map features as an extension BinTable HDU
        hdu = fits.HDUList([pri_hdu, sec_hdu])
        hdu.writeto(self.filename, overwrite=True, checksum=True)