Commit 434bacee602ce01080696a9970f4cc1bcfea9cc7

Authored by Jürgen Knödlseder
1 parent 4b4fc800

Add collection of HKD datasets (#4209)

ChangeLog
1   -2023-03-15
  1 +2023-03-22
2 2  
3 3 * Version 2.1.0 released
4 4 ========================
5 5  
  6 + Add collection of HKD datasets to comgendb (#4209)
6 7 Replace distutils by setuptools for Python setup (#4223)
7 8 Add support for DRW weighting cubes (#4209)
8 9 Prefit models without test source in comlixmap (#4201)
... ...
1 1 New Features and Important Changes in ctools 2.1.0
2 2  
3   -15 March 2023
  3 +22 March 2023
4 4  
5 5  
6 6 Introduction
... ... @@ -324,7 +324,9 @@ None
324 324  
325 325 comgendb - Generate COMPTEL database
326 326 ------------------------------------
327   -None
  327 +Add collection of HKD datasets to script and assure that each HKD datasets
  328 +is covered by an OAD dataset. OAD datasets for which no HKD dataset exists
  329 +will be removed in the XML file (#4209).
328 330  
329 331  
330 332 comlixfit - COMPTEL maximum likelihood fitting using SRCLIX algorithm
... ...
doc/source/admin/release_history/2.1.rst
... ... @@ -31,7 +31,7 @@ Improvements
31 31 ------------
32 32  
33 33 * [`4209 <https://cta-redmine.irap.omp.eu/issues/4209>`_] -
34   - Add support for DRW weighting cubes
  34 + Add support for DRW weighting cubes. Add collection of HKD datasets to :ref:`comgendb`.
35 35 * [`4201 <https://cta-redmine.irap.omp.eu/issues/4201>`_] -
36 36 Prefit models without test source in :ref:`comlixmap`
37 37  
... ...
modules/comscripts/comgendb.py
... ... @@ -2,7 +2,7 @@
2 2 # ==========================================================================
3 3 # Generate COMPTEL database from HEASARC archive
4 4 #
5   -# Copyright (C) 2022 Juergen Knoedlseder
  5 +# Copyright (C) 2022-2023 Juergen Knoedlseder
6 6 #
7 7 # This program is free software: you can redistribute it and/or modify
8 8 # it under the terms of the GNU General Public License as published by
... ... @@ -45,6 +45,7 @@ class comgendb(ctools.cscript):
45 45 # Initialise members
46 46 self._evp_list = []
47 47 self._oad_list = []
  48 + self._hkd_list = []
48 49 self._tim_list = []
49 50 self._xml_list = []
50 51  
... ... @@ -573,7 +574,7 @@ class comgendb(ctools.cscript):
573 574 tics_stop = tics[nrecords-1]
574 575 except:
575 576 self._log_string(gammalib.NORMAL, '*** Corrupt OAD file "%s" encountered. '
576   - 'Set OAD quality to -200.' % (evpname))
  577 + 'Set OAD quality to -200.' % (oadname))
577 578 tjd_start = records.integer('VISDAY')
578 579 tics_start = records.integer('VISTIM')
579 580 tjd_stop = records.integer('VIEDAY')
... ... @@ -612,6 +613,193 @@ class comgendb(ctools.cscript):
612 613 # Return information
613 614 return oad_dict
614 615  
  616 + def _get_hkd_list(self):
  617 + """
  618 + Get HKD list
  619 +
  620 + Returns
  621 + -------
  622 + hkd_list : list of dict
  623 + HKD database
  624 + """
  625 + # Initialse HKD list
  626 + hkd_list = []
  627 +
  628 + # Get available phases
  629 + phases = self._get_phases()
  630 +
  631 + # Loop over phases
  632 + for phase in phases:
  633 +
  634 + # Get available VPs
  635 + vps = glob.glob('%s/vp*' % phase)
  636 + vps.sort()
  637 +
  638 + # Loop over VPs
  639 + for vp in vps:
  640 +
  641 + # Get HKDs for VP
  642 + hkds = self._get_hkds_for_vp(vp)
  643 +
  644 + # Append HKDs to list
  645 + hkd_list.extend(hkds)
  646 +
  647 + # Sort HK list by start day
  648 + hkd_list = self._sorted(hkd_list)
  649 +
  650 + # Return HKD list
  651 + return hkd_list
  652 +
  653 + def _get_hkds_for_vp(self, vp):
  654 + """
  655 + Build HKD database entries for Viewing Period
  656 +
  657 + Parameters
  658 + ----------
  659 + vp : str
  660 + VP path
  661 +
  662 + Returns
  663 + -------
  664 + hkd_list : list of dict
  665 + HKD database entries
  666 + """
  667 + # Get archive name and expanded path
  668 + archive = self['archive'].string()
  669 + archive_path = gammalib.expand_env(archive)
  670 +
  671 + # Get VP name
  672 + vpname = os.path.basename(vp)
  673 +
  674 + # Initialse HKD list
  675 + hkd_list = []
  676 +
  677 + # Get HKD files
  678 + hkds = glob.glob('%s/*hkd.fits*' % vp)
  679 +
  680 + # Loop over all HKD files
  681 + for hkd in hkds:
  682 +
  683 + # Set HKD filename
  684 + hkdname = archive+'/'+self._get_relpath(hkd, archive_path).strip('.gz')
  685 +
  686 + # Try opening file
  687 + try:
  688 + fits = gammalib.GFits(hkdname)
  689 + except:
  690 + self._log_string(gammalib.NORMAL, '*** Unable to open HKD file "%s". '
  691 + 'Skip file.' % (hkdname))
  692 + continue
  693 +
  694 + # Get information from HKD file
  695 + hkd_dict = self._get_hkd_info(hkdname)
  696 +
  697 + # Skip file if it has a negative quality
  698 + if hkd_dict['quality'] < 0:
  699 + self._log_string(gammalib.NORMAL, '*** HKD file "%s" has quality %d. '
  700 + 'Skip file.' % (hkdname, hkd_dict['quality']))
  701 + continue
  702 +
  703 + # Set VP
  704 + hkd_dict['vp'] = vpname
  705 +
  706 + # Append dictionary
  707 + hkd_list.append(hkd_dict)
  708 +
  709 + # Sort HKD list by start day
  710 + hkd_list = self._sorted(hkd_list)
  711 +
  712 + # Return HKD list
  713 + return hkd_list
  714 +
  715 + def _get_hkd_info(self, hkdname):
  716 + """
  717 + Build HKD database entry from HKD file
  718 +
  719 + Parameters
  720 + ----------
  721 + hkdname : str
  722 + HKD filename
  723 +
  724 + Returns
  725 + -------
  726 + hkd_dict : dict
  727 + HKD database entry
  728 + """
  729 + # Open OAD file
  730 + fits = gammalib.GFits(hkdname)
  731 +
  732 + # Get superpacket table
  733 + records = fits.table(1)
  734 + nrecords = records.nrows()
  735 +
  736 + # Extract attributes for HKD file
  737 + obs_id = records.real('OBS_ID')
  738 + object = records.string('OBJECT')
  739 + if records.has_card('GLON_SCZ'):
  740 + glon_scz = records.real('GLON_SCZ')
  741 + else:
  742 + glon_scz = -1000.0
  743 + if records.has_card('GLAT_SCZ'):
  744 + glat_scz = records.real('GLAT_SCZ')
  745 + else:
  746 + glat_scz = -1000.0
  747 + quality = records.integer('DSD_QUA')
  748 + dsd_id = '%s-%s-%d' % (records.string('DSD_SB'), records.string('DSTID'),
  749 + records.integer('DSD_NO'))
  750 +
  751 + # Get time columns
  752 + tjd = records['TJD']
  753 + tics = records['TICS']
  754 +
  755 + # Get start and end time. Catch any errors since files may be corrupt.
  756 + # In case of errors, use times from file header.
  757 + try:
  758 + tjd_start = tjd[0]
  759 + tics_start = tics[0]
  760 + tjd_stop = tjd[nrecords-1]
  761 + tics_stop = tics[nrecords-1]
  762 + except:
  763 + self._log_string(gammalib.NORMAL, '*** Corrupt HKD file "%s" encountered. '
  764 + 'Set HKD quality to -200.' % (hkdname))
  765 + tjd_start = records.integer('VISDAY')
  766 + tics_start = records.integer('VISTIM')
  767 + tjd_stop = records.integer('VIEDAY')
  768 + tics_stop = records.integer('VIETIM')
  769 + quality = -200
  770 +
  771 + # Compute GTime of first and last entry
  772 + tstart = gammalib.com_time(tjd_start, tics_start)
  773 + tstop = gammalib.com_time(tjd_stop, tics_stop)
  774 +
  775 + # Set GTI for HKD
  776 + gti = gammalib.GGti(tstart, tstop)
  777 +
  778 + # Build dictionary
  779 + hkd_dict = {'filename': hkdname,
  780 + 'records': nrecords,
  781 + 'obs_id': obs_id,
  782 + 'dsd_id': dsd_id,
  783 + 'object': object,
  784 + 'glon_scz': glon_scz,
  785 + 'glat_scz': glat_scz,
  786 + 'date_start': tstart.utc(),
  787 + 'date_stop': tstop.utc(),
  788 + 'tjd_start': tjd_start,
  789 + 'tics_start': tics_start,
  790 + 'tjd_stop': tjd_stop,
  791 + 'tics_stop': tics_stop,
  792 + 'tstart': tstart,
  793 + 'tstop': tstop,
  794 + 'gti': gti,
  795 + 'quality': quality}
  796 +
  797 + # Close FITS file
  798 + fits.close()
  799 +
  800 + # Return information
  801 + return hkd_dict
  802 +
615 803 def _get_tim_list(self):
616 804 """
617 805 Get TIM list
... ... @@ -810,9 +998,9 @@ class comgendb(ctools.cscript):
810 998 # Return information
811 999 return tim_dict
812 1000  
813   - def _get_xml_list(self, evp_list, tim_list, oad_list):
  1001 + def _get_xml_list(self, evp_list, tim_list, oad_list, hkd_list):
814 1002 """
815   - Build XML database from EVP, TIM and OAD database
  1003 + Build XML database from EVP, TIM, OAD and HKD database
816 1004  
817 1005 Parameters
818 1006 ----------
... ... @@ -822,6 +1010,8 @@ class comgendb(ctools.cscript):
822 1010 TIM database
823 1011 oad_list : list of dict
824 1012 OAD database
  1013 + hkd_list : list of dict
  1014 + HKD database
825 1015  
826 1016 Returns
827 1017 -------
... ... @@ -848,7 +1038,7 @@ class comgendb(ctools.cscript):
848 1038 for vp in vps:
849 1039  
850 1040 # Get XML for VP
851   - xml = self._get_xml_for_vp(vp, evp_list, filtered_tim_list, oad_list)
  1041 + xml = self._get_xml_for_vp(vp, evp_list, filtered_tim_list, oad_list, hkd_list)
852 1042  
853 1043 # Append XML to list
854 1044 if xml is not None:
... ... @@ -918,7 +1108,7 @@ class comgendb(ctools.cscript):
918 1108 # Return
919 1109 return filtered_tim_list
920 1110  
921   - def _get_xml_for_vp(self, vp, evp_list, tim_list, oad_list):
  1111 + def _get_xml_for_vp(self, vp, evp_list, tim_list, oad_list, hkd_list):
922 1112 """
923 1113 Build XML database entry for Viewing Period
924 1114  
... ... @@ -932,6 +1122,8 @@ class comgendb(ctools.cscript):
932 1122 TIM database
933 1123 oad_list : list of dict
934 1124 OAD database
  1125 + hkd_list : list of dict
  1126 + HKD database
935 1127  
936 1128 Returns
937 1129 -------
... ... @@ -982,15 +1174,46 @@ class comgendb(ctools.cscript):
982 1174 'Skip VP.' % (vp))
983 1175 return None
984 1176  
  1177 + # Get HKDs for EVP
  1178 + hkds = self._get_hkds(evp, hkd_list)
  1179 + if len(hkds) == 0:
  1180 + self._log_string(gammalib.NORMAL, '*** No HKD files found for "%s". '
  1181 + 'Skip VP.' % (vp))
  1182 + return None
  1183 +
  1184 + # Remove OADs that are not covered by HKDs
  1185 + oads_selected = []
  1186 + for oad in oads:
  1187 + tjd_start = oad['tjd_start']
  1188 + tjd_stop = oad['tjd_stop']
  1189 + match = False
  1190 + for hkd in hkds:
  1191 + if tjd_start == hkd['tjd_start'] and \
  1192 + tjd_stop == hkd['tjd_stop']:
  1193 + match = True
  1194 + break
  1195 + if not match:
  1196 + self._log_string(gammalib.NORMAL, '*** No HKD file found for TJD '
  1197 + '%d for "%s". Remove corresponding OAD.' %
  1198 + (tjd_start, vp))
  1199 + else:
  1200 + oads_selected.append(oad)
  1201 + oads = oads_selected
  1202 +
985 1203 # Get oadnames and oad qualities
986 1204 oadnames = [oad['filename'] for oad in oads]
987 1205 oadqualities = [oad['quality'] for oad in oads]
988 1206  
  1207 + # Get hkdnames and hkd qualities
  1208 + hkdnames = [hkd['filename'] for hkd in hkds]
  1209 + hkdqualities = [hkd['quality'] for hkd in hkds]
  1210 +
989 1211 # Build dictionary
990 1212 xml_dict = {'vp': vpname,
991 1213 'evpname': evp['filename'],
992 1214 'timname': tim['filename'],
993 1215 'oadnames': oadnames,
  1216 + 'hkdnames': hkdnames,
994 1217 'xmlname': '%s/xml/%s.xml' % (path, vpname),
995 1218 'nevents': evp['nevents'],
996 1219 'obs_id': evp['obs_id'],
... ... @@ -1014,7 +1237,8 @@ class comgendb(ctools.cscript):
1014 1237 'evp_verno': evp['verno'],
1015 1238 'evp_quality': evp['quality'],
1016 1239 'tim_quality': tim['quality'],
1017   - 'oad_quality': oadqualities}
  1240 + 'oad_quality': oadqualities,
  1241 + 'hkd_quality': hkdqualities}
1018 1242  
1019 1243 # Return XML list
1020 1244 return xml_dict
... ... @@ -1226,7 +1450,8 @@ class comgendb(ctools.cscript):
1226 1450 # First check if OAD is already in OAD list. If this is the case,
1227 1451 # and the current OAD corresponds to the VP of the EVP, then replace
1228 1452 # the existing OAD by the current OAD since we prefer having the
1229   - # OAD in the same folder as the EVP. Otherwise we keep the
  1453 + # OAD in the same folder as the EVP. Otherwise we keep the exiting
  1454 + # OAD
1230 1455 exists = False
1231 1456 for i, oad_exist in enumerate(oads):
1232 1457 if oad_exist['dsd_id'] == oad['dsd_id']:
... ... @@ -1247,6 +1472,59 @@ class comgendb(ctools.cscript):
1247 1472 # Return OADs
1248 1473 return oads
1249 1474  
  1475 + def _get_hkds(self, evp, hkd_list):
  1476 + """
  1477 + Get HKD database entry for EVP database entry
  1478 +
  1479 + Parameters
  1480 + ----------
  1481 + evp : dict
  1482 + EVP dictionary
  1483 + hkd_list : list of dict
  1484 + HKD database
  1485 +
  1486 + Returns
  1487 + -------
  1488 + hkds : list of dict
  1489 + HKD database entries for EVP database entry
  1490 + """
  1491 + # Initialise list of HKDs
  1492 + hkds = []
  1493 +
  1494 + # Loop over all HKDs
  1495 + for hkd in hkd_list:
  1496 +
  1497 + # Compute overlap between EVP and HKD
  1498 + overlap = evp['gti'].overlap(hkd['tstart'], hkd['tstop'])
  1499 +
  1500 + # If we have overlap then check if the file already exists
  1501 + if overlap > 0.0:
  1502 +
  1503 + # First check if HKD is already in HKD list. If this is the case,
  1504 + # and the current HKD corresponds to the VP of the EVP, then replace
  1505 + # the existing HKD by the current HKD since we prefer having the
  1506 + # HKD in the same folder as the EVP. Otherwise we keep the existing
  1507 + # HKD
  1508 + exists = False
  1509 + for i, hkd_exist in enumerate(hkds):
  1510 + if hkd_exist['dsd_id'] == hkd['dsd_id']:
  1511 + exists = True
  1512 + if hkd['vp'] == evp['vp']:
  1513 + hkds[i] = hkd
  1514 + break
  1515 + else:
  1516 + break
  1517 +
  1518 + # If the HKD does not yet exist then append it now
  1519 + if not exists:
  1520 + hkds.append(hkd)
  1521 +
  1522 + # Sort HKD list by start day
  1523 + hkds = self._sorted(hkds)
  1524 +
  1525 + # Return HKDs
  1526 + return hkds
  1527 +
1250 1528 def _check_xml_list(self, xml_list):
1251 1529 """
1252 1530 Check XML list against COMPASS database
... ... @@ -1488,6 +1766,10 @@ class comgendb(ctools.cscript):
1488 1766 for oadname in xml_dict['oadnames']:
1489 1767 obs.append('parameter name="OAD" file="%s"' % (oadname))
1490 1768  
  1769 + # Append HKD files
  1770 + for hkdname in xml_dict['hkdnames']:
  1771 + obs.append('parameter name="HKD" file="%s"' % (hkdname))
  1772 +
1491 1773 # Save XML file
1492 1774 xml.save(xml_dict['xmlname'])
1493 1775  
... ... @@ -1537,7 +1819,7 @@ class comgendb(ctools.cscript):
1537 1819 # Return
1538 1820 return
1539 1821  
1540   - def _build_database_file(self, evp_list, oad_list, tim_list, xml_list):
  1822 + def _build_database_file(self, evp_list, oad_list, hkd_list, tim_list, xml_list):
1541 1823 """
1542 1824 Build database file
1543 1825  
... ... @@ -1547,6 +1829,8 @@ class comgendb(ctools.cscript):
1547 1829 EVP database
1548 1830 oad_list : list of dict
1549 1831 OAD database
  1832 + hkd_list : list of dict
  1833 + HKD database
1550 1834 tim_list : list of dict
1551 1835 TIM database
1552 1836 xml_list : list of dict
... ... @@ -1561,12 +1845,14 @@ class comgendb(ctools.cscript):
1561 1845 # Get tables
1562 1846 evp_table = self._build_evp_table(evp_list)
1563 1847 oad_table = self._build_oad_table(oad_list)
  1848 + hkd_table = self._build_hkd_table(hkd_list)
1564 1849 tim_table = self._build_tim_table(tim_list)
1565 1850 xml_table = self._build_xml_table(xml_list)
1566 1851  
1567 1852 # Append tables
1568 1853 fits.append(evp_table)
1569 1854 fits.append(oad_table)
  1855 + fits.append(hkd_table)
1570 1856 fits.append(tim_table)
1571 1857 fits.append(xml_table)
1572 1858  
... ... @@ -1770,6 +2056,92 @@ class comgendb(ctools.cscript):
1770 2056 # Return table
1771 2057 return table
1772 2058  
  2059 + def _build_hkd_table(self, hkd_list):
  2060 + """
  2061 + Build HKD FITS table
  2062 +
  2063 + Parameters
  2064 + ----------
  2065 + hkd_list : list of dict
  2066 + HKD database
  2067 +
  2068 + Returns
  2069 + -------
  2070 + table : `~gammalib.GFitsBinTable`
  2071 + HKD FITS table
  2072 + """
  2073 + # Determine number of rows in table
  2074 + nrows = len(hkd_list)
  2075 +
  2076 + # Create FITS table columns
  2077 + col_vp = gammalib.GFitsTableStringCol('VP', nrows, 9)
  2078 + col_object = gammalib.GFitsTableStringCol('OBJECT', nrows, 20)
  2079 + col_obs_id = gammalib.GFitsTableStringCol('OBS_ID', nrows, 9)
  2080 + col_dsd_id = gammalib.GFitsTableStringCol('DSD_ID', nrows, 15)
  2081 + col_glon_scz = gammalib.GFitsTableFloatCol('GLON_SCZ', nrows)
  2082 + col_glat_scz = gammalib.GFitsTableFloatCol('GLAT_SCZ', nrows)
  2083 + col_date_start = gammalib.GFitsTableStringCol('DATE_START', nrows, 20)
  2084 + col_date_stop = gammalib.GFitsTableStringCol('DATE_STOP', nrows, 20)
  2085 + col_tjd_start = gammalib.GFitsTableShortCol('TJD_START', nrows)
  2086 + col_tics_start = gammalib.GFitsTableLongCol('TICS_START', nrows)
  2087 + col_tjd_stop = gammalib.GFitsTableShortCol('TJD_STOP', nrows)
  2088 + col_tics_stop = gammalib.GFitsTableLongCol('TICS_STOP', nrows)
  2089 + col_quality = gammalib.GFitsTableShortCol('QUALITY', nrows)
  2090 + col_hkd = gammalib.GFitsTableStringCol('HKD', nrows, 60)
  2091 + col_records = gammalib.GFitsTableLongCol('RECORDS', nrows)
  2092 +
  2093 + # Set column units
  2094 + col_glon_scz.unit('deg')
  2095 + col_glat_scz.unit('deg')
  2096 + col_tjd_start.unit('days')
  2097 + col_tics_start.unit('0.000125 s')
  2098 + col_tjd_stop.unit('days')
  2099 + col_tics_stop.unit('0.000125 s')
  2100 +
  2101 + # Fill columns
  2102 + for i, hkd_record in enumerate(hkd_list):
  2103 + col_vp[i] = hkd_record['vp']
  2104 + col_object[i] = hkd_record['object']
  2105 + col_obs_id[i] = '%.1f' % hkd_record['obs_id']
  2106 + col_dsd_id[i] = hkd_record['dsd_id']
  2107 + col_glon_scz[i] = hkd_record['glon_scz']
  2108 + col_glat_scz[i] = hkd_record['glat_scz']
  2109 + col_date_start[i] = hkd_record['date_start']
  2110 + col_date_stop[i] = hkd_record['date_stop']
  2111 + col_tjd_start[i] = hkd_record['tjd_start']
  2112 + col_tics_start[i] = hkd_record['tics_start']
  2113 + col_tjd_stop[i] = hkd_record['tjd_stop']
  2114 + col_tics_stop[i] = hkd_record['tics_stop']
  2115 + col_quality[i] = hkd_record['quality']
  2116 + col_hkd[i] = hkd_record['filename']
  2117 + col_records[i] = hkd_record['records']
  2118 +
  2119 + # Create FITS table
  2120 + table = gammalib.GFitsBinTable()
  2121 +
  2122 + # Append columns to table
  2123 + table.append(col_vp)
  2124 + table.append(col_object)
  2125 + table.append(col_obs_id)
  2126 + table.append(col_dsd_id)
  2127 + table.append(col_glon_scz)
  2128 + table.append(col_glat_scz)
  2129 + table.append(col_date_start)
  2130 + table.append(col_date_stop)
  2131 + table.append(col_tjd_start)
  2132 + table.append(col_tics_start)
  2133 + table.append(col_tjd_stop)
  2134 + table.append(col_tics_stop)
  2135 + table.append(col_quality)
  2136 + table.append(col_hkd)
  2137 + table.append(col_records)
  2138 +
  2139 + # Set extension name
  2140 + table.extname('HKD')
  2141 +
  2142 + # Return table
  2143 + return table
  2144 +
1773 2145 def _build_tim_table(self, tim_list):
1774 2146 """
1775 2147 Build TIM FITS table
... ... @@ -1903,10 +2275,12 @@ class comgendb(ctools.cscript):
1903 2275 col_evp_quality = gammalib.GFitsTableShortCol('EVP_QUALITY', nrows)
1904 2276 col_tim_quality = gammalib.GFitsTableShortCol('TIM_QUALITY', nrows)
1905 2277 col_oad_quality = gammalib.GFitsTableShortCol('OAD_QUALITY', nrows, 43)
  2278 + col_hkd_quality = gammalib.GFitsTableShortCol('HKD_QUALITY', nrows, 43)
1906 2279 col_xml = gammalib.GFitsTableStringCol('XML', nrows, 60)
1907 2280 col_evp = gammalib.GFitsTableStringCol('EVP', nrows, 60)
1908 2281 col_tim = gammalib.GFitsTableStringCol('TIM', nrows, 60)
1909 2282 col_oad = gammalib.GFitsTableStringCol('OAD', nrows, 60, 43)
  2283 + col_hkd = gammalib.GFitsTableStringCol('HKD', nrows, 60, 43)
1910 2284 col_nevents = gammalib.GFitsTableLongCol('NEVENTS', nrows)
1911 2285 col_model = gammalib.GFitsTableStringCol('MODE', nrows, 8)
1912 2286  
... ... @@ -1954,6 +2328,10 @@ class comgendb(ctools.cscript):
1954 2328 col_oad_quality[i,k] = oad_quality
1955 2329 for k, oadname in enumerate(xml_record['oadnames']):
1956 2330 col_oad[i,k] = oadname
  2331 + for k, hkd_quality in enumerate(xml_record['hkd_quality']):
  2332 + col_hkd_quality[i,k] = hkd_quality
  2333 + for k, hkdname in enumerate(xml_record['hkdnames']):
  2334 + col_hkd[i,k] = hkdname
1957 2335 mode = 'UNKNOWN'
1958 2336 if xml_record['mode'] == 'STD':
1959 2337 mode = 'STANDARD'
... ... @@ -1987,10 +2365,12 @@ class comgendb(ctools.cscript):
1987 2365 table.append(col_evp_quality)
1988 2366 table.append(col_tim_quality)
1989 2367 table.append(col_oad_quality)
  2368 + table.append(col_hkd_quality)
1990 2369 table.append(col_xml)
1991 2370 table.append(col_evp)
1992 2371 table.append(col_tim)
1993 2372 table.append(col_oad)
  2373 + table.append(col_hkd)
1994 2374  
1995 2375 # Set extension name
1996 2376 table.extname('XML')
... ... @@ -2024,6 +2404,12 @@ class comgendb(ctools.cscript):
2024 2404 self._oad_list = self._get_oad_list()
2025 2405  
2026 2406 # Log header
  2407 + self._log_header1(gammalib.TERSE, 'Get list of HKD files')
  2408 +
  2409 + # Get HKD list
  2410 + self._hkd_list = self._get_hkd_list()
  2411 +
  2412 + # Log header
2027 2413 self._log_header1(gammalib.TERSE, 'Get list of TIM files')
2028 2414  
2029 2415 # Get TIM list
... ... @@ -2033,7 +2419,7 @@ class comgendb(ctools.cscript):
2033 2419 self._log_header1(gammalib.TERSE, 'Generate list of XML files')
2034 2420  
2035 2421 # Get XML list
2036   - xml_list = self._get_xml_list(self._evp_list, self._tim_list, self._oad_list)
  2422 + xml_list = self._get_xml_list(self._evp_list, self._tim_list, self._oad_list, self._hkd_list)
2037 2423  
2038 2424 # Log header
2039 2425 self._log_header1(gammalib.TERSE, 'Compare with COMPASS database')
... ... @@ -2064,7 +2450,8 @@ class comgendb(ctools.cscript):
2064 2450  
2065 2451 # Build database file
2066 2452 self._build_database_file(self._evp_list, self._oad_list,
2067   - self._tim_list, self._xml_list)
  2453 + self._hkd_list, self._tim_list,
  2454 + self._xml_list)
2068 2455  
2069 2456 # Return
2070 2457 return
... ...