Esempio n. 1
0
def run_peakfit(dg, config, db_ecal):
    """
    """
    print('\nRunning peakfit ...')

    # do the analysis
    gb = dg.fileDB.groupby(config['gb_cols'])
    gb_args = [config, db_ecal]
    result = gb.apply(peakfit_group, *gb_args)

    # write the results
    if config['write_db']:

        # write separate tables for each energy estimator to the TinyDB
        for epar in config['rawe']:

            # format output
            epar_cols = [r for r in result.columns if epar in r]
            df_epar = result[epar_cols].copy()
            df_epar.rename(columns={c: c.split('_')[-1]
                                    for c in epar_cols},
                           inplace=True)
            df_epar['tsgen'] = int(time.time())
            df_epar.reset_index(inplace=True)
            df_epar['run'] = df_epar['run'].astype(str)

            # write the DataFrame to JSON TinyDB
            table = db_ecal.table(f'peakfit_{epar}')
            query = db.Query()
            for i, row in df_epar.iterrows():
                table.upsert(row.to_dict(), query['run'] == row['run'])

        # show in-memory state and then write to file
        pprint(db_ecal.storage.read())
        pmd.write_pretty(db_ecal.storage.read(), config['ecaldb'])
Esempio n. 2
0
def init_ecaldb(config):
    """
    one-time set up of primary database file
    """
    ans = input('(Re)create main ecal JSON file?  Are you really sure? (y/n) ')
    if ans.lower() != 'y':
        exit()

    f_db = config['ecaldb']  # for pgt, should have one for each detector

    if os.path.exists(f_db):
        os.remove(f_db)

    # create the database in-memory
    db_ecal = db.TinyDB(storage=MemoryStorage)
    query = db.Query()

    # create a table with metadata (provenance) about this calibration file
    file_info = {
        "system": config['system'],
        "cal_type": "energy",
        "created_gmt": datetime.utcnow().strftime("%m/%d/%Y, %H:%M:%S"),
        "input_table": config['input_table']
    }
    db_ecal.table('_file_info').insert(file_info)

    # pretty-print the JSON database to file
    raw_db = db_ecal.storage.read()
    pmd.write_pretty(raw_db, f_db)

    # show the file as-is on disk
    with open(f_db) as f:
        print(f.read())
Esempio n. 3
0
def run_peakfit(dg, config, db_ecal):
    """
    $ ./energy_cal.py -q 'query' -pf [-pi KEY] [-p : show plot]
    
    Using the first guess calibration from peakdet, fit each peak of interest
    and compute the calibration and resolution curves.
    """
    gb = dg.fileDB.groupby(config['gb_cols'])
    runs = dg.fileDB.run.unique()
    cyclo, cychi = dg.fileDB.cycle.iloc[0], dg.fileDB.cycle.iloc[-1]
    print(f'Running peakfit, runs {runs}, cycles {cyclo}--{cychi}')

    result = gb.apply(peakfit, *[config, db_ecal])

    def parse_results(df_run):
        """
        for each run, compute entries for each energy estimator for TinyDB
        """
        run = int(df_run.index[0])

        for epar in config['rawe']:

            # format output
            epar_cols = [r for r in df_run.columns if epar in r]
            df_epar = df_run[epar_cols].copy()
            df_epar.rename(columns={c: c.split('_')[-1]
                                    for c in epar_cols},
                           inplace=True)
            df_epar.reset_index(inplace=True)

            if 'cycle' in df_epar.columns:
                # this is redundant with cyclo and cychi
                df_epar.drop('cycle', 1, inplace=True)
            cyclo, cychi = df_epar.iloc[0][['cyclo', 'cychi']]

            tb_name = f'peakfit_{epar}'
            print('Results:', tb_name)
            print(f'Run {run}  cycles {cyclo}--{cychi}')
            print(df_epar)

            # this is in-memory, no write to file yet
            table = db_ecal.table(tb_name)
            q = db.Query()
            for i, row in df_epar.iterrows():
                que = ((q.run == row.run) & (q.cyclo == row.cyclo) &
                       (q.cychi == row.cychi))
                table.upsert(row.to_dict(), que)

    # parse the results
    result.groupby(['run']).apply(parse_results)

    if not config['write_db']:
        print('Done. ecalDB write mode not set (-w option)')
        return

    # show in-memory state and then write to file
    # pprint(db_ecal.storage.read())
    print('Writing results to ecalDB.')
    pmd.write_pretty(db_ecal.storage.read(), config['ecaldb'])
Esempio n. 4
0
def run_peakdet(dg, config, db_ecal):
    """
    $ ./energy_cal.py -q 'query' -p1 [-p : show plot]
    Run "first guess" calibration of an arbitrary energy estimator.

    NOTE: if you use too high a peakdet threshold, you may not capture
    all the lines you're looking for.  If it's too low, then you have
    to deal with more lines than you probably want for this 1-pt calibration.
    We include an option to show a diagnostic plot for this reason.
    """
    print('\nRunning peakdet ...')

    # do the analysis
    gb = dg.fileDB.groupby(config['gb_cols'])
    gb_args = [config]
    run_no = np.array(dg.fileDB['run'])[0]

    print(f'Running peakdet for run: {run_no}')

    result = gb.apply(peakdet_group, *gb_args)

    # write the results
    if config['write_db']:

        # write separate tables for each energy estimator to the TinyDB
        for epar in config['rawe']:

            # format output
            epar_cols = [r for r in result.columns if epar in r]
            df_epar = result[epar_cols].copy()
            df_epar.rename(columns={c: c.split('_')[-1]
                                    for c in epar_cols},
                           inplace=True)
            df_epar['tsgen'] = int(time.time())
            df_epar.reset_index(inplace=True)
            df_epar['run'] = df_epar['run'].astype(str)

            # write the DataFrame to JSON TinyDB
            table = db_ecal.table(f'peakdet_{epar}')
            query = db.Query()
            for i, row in df_epar.iterrows():
                table.upsert(row.to_dict(), query['run'] == row['run'])

        # show in-memory state and then write to file
        pprint(db_ecal.storage.read())
        pmd.write_pretty(db_ecal.storage.read(), config['ecaldb'])
Esempio n. 5
0
def run_peakdet(dg, config, db_ecal):
    """
    $ ./energy_cal.py -q 'query' [-pd / -pi inp_id] [-p : show plot] [-w : write ecalDB]
    
    Run "first guess" calibration of a list of energy parameters.
    Creates a table in the ecalDB for each one, storing up to 2nd order
    polynomials: y = p0  +  p1 * x  +  p2 * x**2.
    These are used as inputs to "peakfit".

    We have two modes:
    -- automatic (default): find p1 by matching the ratios of uncalibrated
       auto-detected peaks to an input list of peaks in keV.  
       Assumes y = p1 * x, which may not always work for all detectors.
       
    -- "input peaks": use a JSON config file to set expected peak locations.
       This is useful when the spectrum deviates too much from y = p1 * x.
          
    Files are grouped by run, and optionally by cycle (calibrates individual files
      within the run.)  Right now, we require the first item in gb_cols to be 'run'.
      It's also possible to group a subset of files in a run together, with a 
      query like "run==123 and cycle > 456"

    We then write several TinyDB 'Tables' to our ecalDB file.  
    They have a nice 1--1 correspondence to pandas dataframes.
    """
    gb = dg.fileDB.groupby(config['gb_cols'])
    runs = dg.fileDB.run.unique()
    cyclo, cychi = dg.fileDB.cycle.iloc[0], dg.fileDB.cycle.iloc[-1]
    print(f'Running peakdet, runs {runs}, cycles {cyclo}--{cychi}')

    # run peakdet function as a pandas groupby
    if 'input_id' in config.keys():
        pol = config['pol'][0]
        print(f'Fitting manually input peak locations to polynomial, order',
              pol)
        result = gb.apply(peakdet_input, *[config])
    else:
        print('Automatically detecting peaks based on input list.')
        result = gb.apply(peakdet_auto, *[config])

    def parse_results(df_run):
        """
        for each run, compute entries for each energy estimator to TinyDB
        """
        run = int(df_run.index[0])

        for epar in config['rawe']:

            # format output table
            epar_cols = [r for r in df_run.columns if epar in r]
            df_epar = df_run[epar_cols].copy()
            df_epar.rename(columns={c: c.split('_')[-1]
                                    for c in epar_cols},
                           inplace=True)
            df_epar['calpass'] = df_epar['calpass'].astype(int)
            df_epar.reset_index(inplace=True)

            if 'cycle' in df_epar.columns:
                # this is redundant with cyclo and cychi
                df_epar.drop('cycle', 1, inplace=True)
            cyclo, cychi = df_epar.iloc[0][['cyclo', 'cychi']]

            tb_name = f'peakinp_{epar}' if 'input_id' in config.keys(
            ) else f'peakdet_{epar}'
            print('Results:', tb_name)
            print(f'Run {run}  cycles {cyclo}--{cychi}')
            print(df_epar)

            # this is in-memory, no write to file yet
            table = db_ecal.table(tb_name)
            q = db.Query()
            for i, row in df_epar.iterrows():
                que = ((q.run == row.run) & (q.cyclo == row.cyclo) &
                       (q.cychi == row.cychi))
                table.upsert(row.to_dict(), que)

    # parse the results
    result.groupby(['run']).apply(parse_results)

    if not config['write_db']:
        print('Done. ecalDB write mode not set (-w option)')
        return

    # show in-memory state and then write to file
    # pprint(db_ecal.storage.read())
    print('Writing results to ecalDB.')
    pmd.write_pretty(db_ecal.storage.read(), config['ecaldb'])