def tabgtigen(odf_dir):
    logger.info("TASK: tabgtigen")
    gti_dir = "{}/gti".format(odf_dir)
    rate = glob.glob("{}/rate_*".format(odf_dir))[0]
    os.chdir(gti_dir)
    if (len(rate) == 0):
        logger.info("No rate file found in {}".format(odf_dir))
    else:
        logger.info("Found {} calibrated events list.".format(rate))
    logger.info("Generating Good Time Intervals for {}...".format(rate))
    expo = rate.split('rate')[1]
    gti = 'gti{}'.format(expo)
    logger.info("GTI: {}".format(gti))
    expr = 'RATE<=0.4'
    task = f'tabgtigen table="{rate}" gtiset={gti}' + \
           f' expression=\'{expr}\''
    logger.info("COMMAND: {}".format(task))
    status = exec_task(task)
    if status != 0:
        logger.info(
            "ERROR: Task tabgtigen failed. Check {}/tmp.log for more information"
            .format(odf_dir))
        raise Exception
    os.chdir(odf_dir)
    logger.info("{} generated correctly.".format(gti))
    return gti_dir
def edetect_chain(odf_dir, pi):
    logger.info("TASK: edetect_chain")
    images_dir = odf_dir + "/images"
    os.chdir(images_dir)
    logger.info("Using:")
    #image_low = glob.glob("*_500_2000.fits")[0]
    image_low = glob.glob("*_500_2000_clean.fits")[0]
    logger.info("{}".format(image_low))
    #image_high = glob.glob("*_4500_10000.fits")[0]
    image_high = glob.glob("*_4500_10000_clean.fits")[0]
    logger.info("{}".format(image_high))
    #image_mid = glob.glob("*_2000_4500.fits")[0]
    image_mid = glob.glob("*_2000_4500_clean.fits")[0]
    logger.info("{}".format(image_high))
    clean_evts = glob.glob("{}/clean_*".format(odf_dir))[0]
    logger.info("{}".format(clean_evts))
    attitude_file = glob.glob("{}/atthk*".format(odf_dir))[0]
    logger.info("{}".format(attitude_file))
    ecf = 1  # Cuentas a flujo, nos da igual.
    task = f"edetect_chain imagesets={image_low} eventsets={clean_evts} " + \
           f"attitudeset={attitude_file} pimin={pi[0]} pimax={pi[1]} ecf={ecf} " + \
           "eboxl_list='pn_eboxlist_l_low.fits' eboxm_list='pn_eboxlist_m_low.fits' " + \
           "esp_nsplinenodes=16 eml_list='pn_emllist_low.fits' esen_mlmin=15 -V 5"
    status = exec_task(task)
    if (status != 0):
        print(f"Task \"{task}\" failed")
        raise Exception
    task = f"edetect_chain imagesets={image_high} eventsets={clean_evts} " + \
           f"attitudeset={attitude_file} pimin={pi[2]} pimax={pi[3]} ecf={ecf} " + \
           "eboxl_list='pn_eboxlist_l_high.fits' eboxm_list='pn_eboxlist_m_high.fits' " + \
           "esp_nsplinenodes=16 eml_list='pn_emllist_high.fits' esen_mlmin=15"
    status = exec_task(task)
    if (status != 0):
        logger.info("ERROR: Task edetect_chain failed. Check {}/tmp.log for more information".format(odf_dir))
        raise Exception
    task = f"edetect_chain imagesets={image_mid} eventsets={clean_evts} " + \
           f"attitudeset={attitude_file} pimin={pi[1]} pimax={pi[2]} ecf={ecf} " + \
           "eboxl_list='pn_eboxlist_l_low.fits' eboxm_list='pn_eboxlist_m_low.fits' " + \
           "esp_nsplinenodes=16 eml_list='pn_emllist_low.fits' esen_mlmin=15 -V 5"
    status = exec_task(task)
    if (status != 0):
        print(f"Task \"{task}\" failed")
        raise Exception
    logger.info("Sources detected correctly.")
def ecoordconv(obsid):
    logger.info("TASK: ecoordconv")
    bll_catalog = fits.open('/home/aaranda/tfm/bllacs_PN_NopileupNofasttiming.fits')
    data = bll_catalog[1].data
    RA = ""
    DEC = ""
    for row in data:
        if row[5] == obsid:
            RA = row[1]
            logger.info("COORDINATES: RA: {}".format(RA))
            DEC = row[2]
            logger.info("COORDINATES: DEC: {}".format(DEC))

    if RA == "" and DEC == "":
        logger.info("Coordinates not found in catalog.")
    images_dir = odf_dir + "/images"
    image_low = glob.glob("{}/*_500_2000.fits".format(images_dir))[0]
    coords = []

    task = f'ecoordconv imageset={image_low} x="{RA}" y="{DEC}" coordtype=eqpos'
    logger.info("COMMAND: {}".format(task))
    status = exec_task(task)
    if (status != 0):
        print(f"Task \"{task}\" failed")
        raise Exception

    file = "tmp.log"
    with open(file, "r") as f:
        for line in f:
            if "X: Y:" in line:
                X = float(line.split(" ")[3])
                Y = float(line.split(" ")[4])
                coords.append([X, Y])

    print("X value is {}".format(X))
    print("Y value is {}".format(Y))
    logger.info("COORDINATES: X: {}".format(X))
    logger.info("COORDINATES: Y: {}".format(Y))

    # Delete the corresponding row in bkg_region.ds file.
    bkg_region = fits.open(f'bkg_region.ds', mode='update')
    data = bkg_region[1].data
    err = 50
    count = 0
    bad_row = None
    for row in data:
        if ((X - err) <= row[1][0] <= (X + err)) and ((Y - err) <= row[2][0] <= (Y + err)):
            bad_row = count
        count += 1

    if bad_row != None:
        data = np.delete(data, bad_row)  # !!!maybe repeated rows
    bkg_region[1].data = data
    bkg_region.writeto(f'bkg_region_clean.ds')
    logger.info("RA, DEC obtained correctly.\n\n")
    return [RA, DEC]
def generate_oot_evts(odf_dir):
    logger.info("TASK: epchain")
    os.chdir(odf_dir)
    task = 'epchain runbackground=N keepintermediate=raw withoutoftime=Y'
    status = exec_task(task)
    if status != 0:
        logger.info(
            "ERROR: Task epchain failed. Check {}/tmp.log for more information"
            .format(odf_dir))
        raise Exception
def filtered_region():
    logger.info("TASK: region")
    clean_evts = glob.glob("clean_*")[0]
    filtered_set = "filtered_{}".format(clean_evts)
    expr = f"region(bkg_region_clean.ds)"
    task = f'evselect table={clean_evts} filteredset={filtered_set} '+  \
        f'expression="{expr}"'
    logger.info("COMMAND: {}".format(task))
    status = exec_task(task)
    if (status != 0):
        print (f"Task \"{task}\" failed")
        raise Exception
    logger.info("Image filtered with bkg_region_clean.ds generated correctly.")
def generate_oot_image(odf_dir):
    logger.info("TASK: evselect")
    os.chdir(odf_dir)
    oot_list = glob.glob("*OOEVLI0000.FIT")[0]
    task = f'evselect table={oot_list} imagebinning=binSize \
     imageset=PN_OoT_image.fits withimageset=yes xcolumn=X ycolumn=Y \
     ximagebinsize=80 yimagebinsize=80'

    status = exec_task(task)
    if status != 0:
        logger.info(
            "ERROR: Task evselect failed. Check {}/tmp.log for more information"
            .format(odf_dir))
        raise Exception
def generate_filtered_images(odf_dir, bin_size, pi):
    logger.info("TASK: evselect")
    images_dir = odf_dir + "/images"
    os.chdir(images_dir)
    filtered = glob.glob("{}/filtered_*".format(odf_dir))[0]
    expr_high = f'PI in [{pi[2]}:{pi[3]}] &&  FLAG==0 && PATTERN in [0:4]'
    expr_mid = f'PI in [{pi[1]}:{pi[2]}] &&  FLAG==0 && PATTERN in [0:4]'
    expr_low = f'PI in [{pi[0]}:{pi[1]}] &&  FLAG==0 && PATTERN in [0:4]'

    task = f'evselect table={filtered} xcolumn=X ycolumn=Y imagebinning=binSize' + \
           f' ximagebinsize={bin_size} yimagebinsize={bin_size}' + \
           f' expression=\'{expr_high}\'' + \
           f' withimageset=true imageset=image_filtered_high.fits'
    logger.info("COMMAND: {}\n".format(task))
    status = exec_task(task)
    if (status != 0):
        raise Exception

    task = f'evselect table={filtered} xcolumn=X ycolumn=Y imagebinning=binSize' + \
           f' ximagebinsize={bin_size} yimagebinsize={bin_size}' + \
           f' expression=\'{expr_low}\'' + \
           f' withimageset=true imageset=image_filtered_low.fits'
    logger.info("COMMAND: {}".format(task))
    status = exec_task(task)
    if (status != 0):
        raise Exception

    task = f'evselect table={filtered} xcolumn=X ycolumn=Y imagebinning=binSize' + \
           f' ximagebinsize={bin_size} yimagebinsize={bin_size}' + \
           f' expression=\'{expr_mid}\'' + \
           f' withimageset=true imageset=image_filtered_mid.fits'
    logger.info("COMMAND: {}".format(task))
    status = exec_task(task)
    if (status != 0):
        raise Exception
    os.chdir(odf_dir)
    logger.info("Images generated correctly.")
def evselect(odf_dir):
    logger.info("TASK: evselect")
    os.chdir("{}/pps".format(odf_dir))
    evlist = glob.glob("*PIEVLI0000.fits")[0]
    logger.info("EVENTS LIST: {}".format(evlist))
    expo = evlist.split('PIEVLI0000.fits')[0]
    rate = "{}/rate_{}.fits".format(odf_dir, expo)
    logger.info("RATE: {}".format(rate))
    expr = '#XMMEA_EP && (PI>10000&&PI<12000) && (PATTERN==0)'
    task = f'evselect table={evlist} withrateset=Y rateset={rate}' + \
           ' maketimecolumn=Y timebinsize=100 makeratecolumn=Y' + \
           f' expression=\'{expr}\''
    logger.info("COMMAND: {}".format(task))
    status = exec_task(task)
    if status != 0:
        logger.info(
            "ERROR: Task evselect failed. Check {}/tmp.log for more information"
            .format(odf_dir))
        raise Exception
    logger.info("rate file generated correctly.")
def evselect_clean(odf_dir, gti_dir):
    logger.info("TASK: evselect")
    os.chdir("{}/pps".format(odf_dir))
    evlist = glob.glob("*PIEVLI0000.fits")[0]
    gti = glob.glob("{}/gti_*".format(gti_dir))[0]
    expo = evlist.split('PIEVLI0000.fits')[0]
    logger.info("Using PI>150 for evselect.".format(gti))
    expr = f"#XMMEA_EP && gti({gti},TIME) && (PI>150)"
    task = f'evselect table={evlist} withfilteredset=Y ' + \
           f'filteredset={odf_dir}/clean_{expo}.fits ' + \
           f'destruct=Y keepfilteroutput=T expression=\'{expr}\''
    logger.info("Filtering {} with GTI...".format(expo))
    logger.info("COMMAND: {}".format(task))
    status = exec_task(task)
    if status != 0:
        logger.info(
            "ERROR: Task evselect failed. Check {}/tmp.log for more information"
            .format(odf_dir))
        raise Exception
    logger.info("clean file generated correctly.")
    os.chdir(odf_dir)
def generate_images(odf_dir, bin_size, pi):
    logger.info("TASK: evselect")
    logger.info("ENERGY BAND 1: {} - {} eV".format(pi[0], pi[1]))
    logger.info("ENERGY BAND 2: {} - {} eV".format(pi[1], pi[2]))
    logger.info("ENERGY BAND 3: {} - {} eV".format(pi[2], pi[3]))
    logger.info("BIN SIZE: {}".format(bin_size))
    os.chdir("{}/pps".format(odf_dir))
    evlist = glob.glob("*PIEVLI0000.fits")[0]
    expo = evlist.split('PIEVLI0000.fits')[0]
    clean_file = glob.glob("{}/clean_*".format(odf_dir))[0]
    images_dir = "{}/images".format(odf_dir)
    os.chdir(images_dir)
    image_name = [
        f'image_{expo}_{pi[0]}_{pi[1]}.fits',
        f'image_{expo}_{pi[1]}_{pi[2]}.fits',
        f'image_{expo}_{pi[2]}_{pi[3]}.fits'
    ]
    expr = [
        f'PI in [{pi[0]}:{pi[1]}] &&  FLAG==0 && PATTERN in [0:4]',
        f'PI in [{pi[1]}:{pi[2]}] &&  FLAG==0 && PATTERN in [0:4]',
        f'PI in [{pi[2]}:{pi[3]}] &&  FLAG==0 && PATTERN in [0:4]'
    ]
    for i in range(len(expr)):
        task = f'evselect table={clean_file} xcolumn=X ycolumn=Y imagebinning=binSize' + \
               f' ximagebinsize={bin_size} yimagebinsize={bin_size}' + \
               f' expression=\'{expr[i]}\'' + \
               f' withimageset=true imageset={image_name[i]}'
        logger.info("COMMAND: {}\n".format(task))
        status = exec_task(task)
        if status != 0:
            logger.info(
                "ERROR: Task evselect failed. Check {}/tmp.log for more information"
                .format(odf_dir))
            raise Exception
        logger.info("Image {} generated.".format(image_name[i]))
    logger.info("Images generated correctly.")
def region(odf_dir):
    logger.info("TASK: region")
    os.chdir(odf_dir)
    bkg_file = glob.glob("bkg_*")
    if len(bkg_file) != 0:
        for bkg in bkg_file:
            os.remove(bkg)
    clean_evts = glob.glob("clean_*")[0]
    # Region for OBSMLI downloaded from te pipeline
    src_file = glob.glob("pps/*OBSMLI0000.fits")[0]
    task = f"region eventset={clean_evts} tempset=tempset.ds " + \
        f"srclisttab={src_file} operationstyle='global'"# radiusstyle='contour' outunit='xy' -V 5"

    # ## Region for the srclist from edetect_chain
    # src_file = glob.glob("{}/pn_emllist*".format(images_dir))[0]
    # task = f"region eventset={clean_evts} tempset=tempset.ds " + \
    #     f"srclisttab={src_file} operationstyle='global'"# radiusstyle='contour' outunit='xy' -V 5"

    logger.info("COMMAND: {}".format(task))
    status = exec_task(task)
    if (status != 0):
        print (f"Task \"{task}\" failed")
        raise Exception
    logger.info("bkg file generated correctly.")
def psf_gen(center, energy, box, psf_out):
    psfgen = f'psfgen image={fits_image} withimage=yes instrument=PN level=ELLBETA energy={energy} ' + \
             f'x={center.ra.value} y={center.dec.value} coordtype=EQPOS xsize={box} ysize={box} output={psf_out}'
    status = exec_task(psfgen)
    if (status != 0):
        raise RuntimeError