예제 #1
0
def calibrate_dgs_data(datalist, conf, dkcur, **kwargs):
    """
    This function combines Steps 3 through 6 in Section 2.1.1 of the data
    reduction process for Direct Geometry Spectrometers as specified by the
    document at 
    U{http://neutrons.ornl.gov/asg/projects/SCL/reqspec/DR_Lib_RS.doc}. The
    function takes a list of file names, a L{hlr_utils.Configure} object and
    processes the data accordingly.
    
    @param datalist: A list containing the filenames of the data to be
                     processed.
    @type datalist: C{list} of C{string}s
    
    @param conf: Object that contains the current setup of the driver.
    @type conf: L{hlr_utils.Configure}

    @param dkcur: The object containing the TOF dark current data.
    @type dkcur: C{SOM.SOM}
    
    @param kwargs: A list of keyword arguments that the function accepts:
    
    @keyword inst_geom_dst: File object that contains instrument geometry
                            information.
    @type inst_geom_dst: C{DST.GeomDST}

    @keyword tib_const: A time-independent background constant to subtract
                        from every pixel.
    @type tib_const: L{hlr_utils.DrParameter}
    
    @keyword dataset_type: The practical name of the dataset being processed.
                           The default value is I{data}.
    @type dataset_type: C{string}

    @keyword cwp: A list of chopper phase corrections in units of microseconds.
    @type cwp: C{list} of C{float}s
    
    @keyword timer: Timing object so the function can perform timing estimates.
    @type timer: C{sns_timer.DiffTime}


    @return: Object that has undergone all requested processing steps
    @rtype: C{SOM.SOM}
    """
    import common_lib
    import dr_lib
    import hlr_utils

    # Check keywords
    try:
        tib_const = kwargs["tib_const"]
    except KeyError:
        tib_const = None
    
    try:
        dataset_type = kwargs["dataset_type"]
    except KeyError:
        dataset_type = "data"

    try:
        t = kwargs["timer"]
    except KeyError:
        t = None

    try:
        i_geom_dst = kwargs["inst_geom_dst"]
    except KeyError:
        i_geom_dst = None

    dataset_cwp = kwargs.get("cwp")

    # Open the appropriate datafiles
    if conf.verbose:
        print "Reading %s file" % dataset_type

    data_paths = conf.data_paths.toPath()
    if conf.no_mon_norm:
        mon_paths = None
    else:
        mon_paths = conf.usmon_path.toPath()

    # Check for mask file since normalization drive doesn't understand option
    try:
        mask_file = conf.mask_file
    except AttributeError:
        mask_file = None

    if t is not None:
        oldtime = t.getOldTime()

    (dp_som0, dm_som0) = dr_lib.add_files_dm(datalist, Data_Paths=data_paths,
                                             Mon_Paths=mon_paths,
                                             SO_Axis=conf.so_axis,
                                             Signal_ROI=conf.roi_file,
                                             Signal_MASK=mask_file,
                                             dataset_type=dataset_type,
                                             dataset_cwp=dataset_cwp,
                                             Verbose=conf.verbose, Timer=t)

    if t is not None:
        t.setOldTime(oldtime)
        t.getTime(msg="After reading %s file" % dataset_type)

    # Cut the spectra if necessary
    dp_somA = dr_lib.cut_spectra(dp_som0, conf.tof_cut_min, conf.tof_cut_max)

    del dp_som0

    dp_somB = dr_lib.fix_bin_contents(dp_somA)

    del dp_somA

    if dp_somB.attr_list.instrument.get_name() != "CNCS":

        if conf.verbose:
            print "Cutting spectrum at minimum TOF"
        
        if t is not None:
            t.getTime(False)

        # Calculate minimum TOF for physical neutrons
        if conf.initial_energy is not None:
            initial_wavelength = common_lib.energy_to_wavelength(\
            conf.initial_energy.toValErrTuple())
            initial_velocity = common_lib.wavelength_to_velocity(\
            initial_wavelength)
        else:
            # This should actually calculate it, but don't have a way right now
            pass

        if conf.time_zero_offset is not None:
            time_zero_offset = conf.time_zero_offset.toValErrTuple()
        else:
            # This should actually calculate it, but don't have a way right now
            time_zero_offset = (0.0, 0.0)

        ss_length = dp_somB.attr_list.instrument.get_primary()
        
        tof_min = (ss_length[0] / initial_velocity[0]) + time_zero_offset[0]

        # Cut all spectra a the minimum TOF
        dp_som1 = dr_lib.cut_spectra(dp_somB, tof_min, None)

        if t is not None:
            t.getTime(msg="After cutting spectrum at minimum TOF ")
    else:
        dp_som1 = dp_somB

    del dp_somB

    if dm_som0 is not None:
        dm_som1 = dr_lib.fix_bin_contents(dm_som0)
    else:
        dm_som1 = dm_som0

    del dm_som0    

    # Override geometry if necessary
    if conf.inst_geom is not None:
        i_geom_dst.setGeometry(data_paths, dp_som1)

    if conf.inst_geom is not None and dm_som1 is not None:
        i_geom_dst.setGeometry(mon_paths, dm_som1)
    
    # Step 3: Integrate the upstream monitor
    if dm_som1 is not None:
        if conf.verbose:
            print "Integrating upstream monitor spectrum"

        if t is not None:
            t.getTime(False)
        
        if conf.mon_int_range is None:
            start_val = float("inf")
            end_val = float("inf")
        else:
            start_val = conf.mon_int_range[0]
            end_val = conf.mon_int_range[1]
        
        dm_som2 = dr_lib.integrate_spectra(dm_som1, start=start_val,
                                           end=end_val,
                                           width=True)
        if t is not None:
            t.getTime(msg="After integrating upstream monitor spectrum ")
    else:
        dm_som2 = dm_som1

    del dm_som1

    tib_norm_const = None
    
    # Step 4: Divide data set by summed monitor spectrum
    if dm_som2 is not None:
        if conf.verbose:
            print "Normalizing %s by monitor sum" % dataset_type

        if t is not None:
            t.getTime(False)

        dp_som2 = common_lib.div_ncerr(dp_som1, dm_som2, length_one_som=True)

        tib_norm_const = dm_som2[0].y

        if t is not None:
            t.getTime(msg="After normalizing %s by monitor sum" % dataset_type)

    elif conf.pc_norm:
        if conf.verbose:
            print "Normalizing %s by proton charge" % dataset_type

        pc_tag = dataset_type+"-proton_charge"
        pc = dp_som1.attr_list[pc_tag]

        # Scale the proton charge and then set the scale PC back to attributes
        if conf.scale_pc is not None:
            if conf.verbose:
                print "Scaling %s proton charge" % dataset_type

            pc = hlr_utils.scale_proton_charge(pc, conf.scale_pc)
            dp_som1.attr_list[pc_tag] = pc

        tib_norm_const = pc.getValue()

        if t is not None:
            t.getTime(False)

        dp_som2 = common_lib.div_ncerr(dp_som1, (pc.getValue(), 0.0))

        if t is not None:
            t.getTime(msg="After normalizing %s by proton charge" \
                      % dataset_type)

    else:
        dp_som2 = dp_som1

    del dp_som1, dm_som2

    # Step 5: Scale dark current by data set measurement time
    if dkcur is not None:
        if conf.verbose:
            print "Scaling dark current by %s acquisition time" % dataset_type

        if t is not None:
            t.getTime(False)

        dstime_tag = dataset_type+"-duration"
        dstime = dp_som2.attr_list[dstime_tag]

        dkcur1 = common_lib.div_ncerr(dkcur, (dstime.getValue(), 0.0))

        if t is not None:
            t.getTime(msg="After scaling dark current by %s acquisition time" \
                      % dataset_type)        
    else:
        dkcur1 = dkcur

    del dkcur

    # Step 6: Subtract scaled dark current from data set
    if dkcur1 is not None:
        if conf.verbose:
            print "Subtracting %s by scaled dark current" % dataset_type

        if t is not None:
            t.getTime(False)

        dp_som3 = common_lib.sub_ncerr(dp_som2, dkcur1)

        if t is not None:
            t.getTime(msg="After subtracting %s by scaled dark current" \
                      % dataset_type)
    elif tib_const is not None and dkcur1 is None:
        if conf.verbose:
            print "Subtracting TIB constant from %s" % dataset_type

        # Normalize the TIB constant by dividing by the current normalization
        # the duration (if necessary) and the conversion from seconds to
        # microseconds
        tib_c = tib_const.toValErrTuple()

        conv_sec_to_usec = 1.0e-6

        if tib_norm_const is None:
            tib_norm_const = 1
            duration = 1
        else:
            duration_tag = dataset_type+"-duration"
            duration = dp_som2.attr_list[duration_tag].getValue()

        norm_const = (duration * conv_sec_to_usec) / tib_norm_const

        tib_val = tib_c[0] * norm_const
        tib_err2 = tib_c[1] * (norm_const * norm_const)

        if t is not None:
            t.getTime(False)
  
        dp_som3 = common_lib.sub_ncerr(dp_som2, (tib_val, tib_err2))

        if t is not None:
            t.getTime(msg="After subtracting TIB constant from %s" \
                      % dataset_type)
    elif conf.tib_range is not None and dkcur1 is None:
        if conf.verbose:
            print "Determining TIB constant from %s" % dataset_type

        if t is not None:
            t.getTime(False)

        TIB = dr_lib.determine_time_indep_bkg(dp_som2, conf.tib_range,
                                              is_range=True)

        if t is not None:
            t.getTime(msg="After determining TIB constant from %s" \
                      % dataset_type)

        if conf.dump_tib:
            file_comment = "TIB TOF Range: [%d, %d]" % (conf.tib_range[0],
                                                        conf.tib_range[1])
        
            hlr_utils.write_file(conf.output, "text/num-info", TIB,
                                 output_ext="tib",
                                 extra_tag=dataset_type,
                                 verbose=conf.verbose,
                                 data_ext=conf.ext_replacement,
                                 path_replacement=conf.path_replacement,
                                 message="time-independent background "\
                                 +"information",
                                 tag="Average TIB",
                                 units="counts/usec",
                                 comments=[file_comment])
            
        if conf.verbose:
            print "Subtracting TIB constant from %s" % dataset_type

        if t is not None:
            t.getTime(False)

        dp_som3 = common_lib.sub_ncerr(dp_som2, TIB)

        if t is not None:
            t.getTime(msg="After subtracting TIB constant from %s" \
                      % dataset_type)

        del TIB
    else:
        dp_som3 = dp_som2

    del dp_som2, dkcur1

    if conf.dump_ctof_comb:
        dp_som3_1 = dr_lib.sum_all_spectra(dp_som3)
        hlr_utils.write_file(conf.output, "text/Spec", dp_som3_1,
                             output_ext="ctof",
                             extra_tag=dataset_type,
                             data_ext=conf.ext_replacement,    
                             path_replacement=conf.path_replacement,
                             verbose=conf.verbose,
                             message="combined calibrated TOF information")
        
        del dp_som3_1
    
    return dp_som3
예제 #2
0
def calibrate_dgs_data(datalist, conf, dkcur, **kwargs):
    """
    This function combines Steps 3 through 6 in Section 2.1.1 of the data
    reduction process for Direct Geometry Spectrometers as specified by the
    document at 
    U{http://neutrons.ornl.gov/asg/projects/SCL/reqspec/DR_Lib_RS.doc}. The
    function takes a list of file names, a L{hlr_utils.Configure} object and
    processes the data accordingly.
    
    @param datalist: A list containing the filenames of the data to be
                     processed.
    @type datalist: C{list} of C{string}s
    
    @param conf: Object that contains the current setup of the driver.
    @type conf: L{hlr_utils.Configure}

    @param dkcur: The object containing the TOF dark current data.
    @type dkcur: C{SOM.SOM}
    
    @param kwargs: A list of keyword arguments that the function accepts:
    
    @keyword inst_geom_dst: File object that contains instrument geometry
                            information.
    @type inst_geom_dst: C{DST.GeomDST}

    @keyword tib_const: A time-independent background constant to subtract
                        from every pixel.
    @type tib_const: L{hlr_utils.DrParameter}
    
    @keyword dataset_type: The practical name of the dataset being processed.
                           The default value is I{data}.
    @type dataset_type: C{string}

    @keyword cwp: A list of chopper phase corrections in units of microseconds.
    @type cwp: C{list} of C{float}s
    
    @keyword timer: Timing object so the function can perform timing estimates.
    @type timer: C{sns_timer.DiffTime}


    @return: Object that has undergone all requested processing steps
    @rtype: C{SOM.SOM}
    """
    import common_lib
    import dr_lib
    import hlr_utils

    # Check keywords
    try:
        tib_const = kwargs["tib_const"]
    except KeyError:
        tib_const = None

    try:
        dataset_type = kwargs["dataset_type"]
    except KeyError:
        dataset_type = "data"

    try:
        t = kwargs["timer"]
    except KeyError:
        t = None

    try:
        i_geom_dst = kwargs["inst_geom_dst"]
    except KeyError:
        i_geom_dst = None

    dataset_cwp = kwargs.get("cwp")

    # Open the appropriate datafiles
    if conf.verbose:
        print "Reading %s file" % dataset_type

    data_paths = conf.data_paths.toPath()
    if conf.no_mon_norm:
        mon_paths = None
    else:
        mon_paths = conf.usmon_path.toPath()

    # Check for mask file since normalization drive doesn't understand option
    try:
        mask_file = conf.mask_file
    except AttributeError:
        mask_file = None

    if t is not None:
        oldtime = t.getOldTime()

    (dp_som0, dm_som0) = dr_lib.add_files_dm(datalist,
                                             Data_Paths=data_paths,
                                             Mon_Paths=mon_paths,
                                             SO_Axis=conf.so_axis,
                                             Signal_ROI=conf.roi_file,
                                             Signal_MASK=mask_file,
                                             dataset_type=dataset_type,
                                             dataset_cwp=dataset_cwp,
                                             Verbose=conf.verbose,
                                             Timer=t)

    if t is not None:
        t.setOldTime(oldtime)
        t.getTime(msg="After reading %s file" % dataset_type)

    # Cut the spectra if necessary
    dp_somA = dr_lib.cut_spectra(dp_som0, conf.tof_cut_min, conf.tof_cut_max)

    del dp_som0

    dp_somB = dr_lib.fix_bin_contents(dp_somA)

    del dp_somA

    if dp_somB.attr_list.instrument.get_name() != "CNCS":

        if conf.verbose:
            print "Cutting spectrum at minimum TOF"

        if t is not None:
            t.getTime(False)

        # Calculate minimum TOF for physical neutrons
        if conf.initial_energy is not None:
            initial_wavelength = common_lib.energy_to_wavelength(\
            conf.initial_energy.toValErrTuple())
            initial_velocity = common_lib.wavelength_to_velocity(\
            initial_wavelength)
        else:
            # This should actually calculate it, but don't have a way right now
            pass

        if conf.time_zero_offset is not None:
            time_zero_offset = conf.time_zero_offset.toValErrTuple()
        else:
            # This should actually calculate it, but don't have a way right now
            time_zero_offset = (0.0, 0.0)

        ss_length = dp_somB.attr_list.instrument.get_primary()

        tof_min = (ss_length[0] / initial_velocity[0]) + time_zero_offset[0]

        # Cut all spectra a the minimum TOF
        dp_som1 = dr_lib.cut_spectra(dp_somB, tof_min, None)

        if t is not None:
            t.getTime(msg="After cutting spectrum at minimum TOF ")
    else:
        dp_som1 = dp_somB

    del dp_somB

    if dm_som0 is not None:
        dm_som1 = dr_lib.fix_bin_contents(dm_som0)
    else:
        dm_som1 = dm_som0

    del dm_som0

    # Override geometry if necessary
    if conf.inst_geom is not None:
        i_geom_dst.setGeometry(data_paths, dp_som1)

    if conf.inst_geom is not None and dm_som1 is not None:
        i_geom_dst.setGeometry(mon_paths, dm_som1)

    # Step 3: Integrate the upstream monitor
    if dm_som1 is not None:
        if conf.verbose:
            print "Integrating upstream monitor spectrum"

        if t is not None:
            t.getTime(False)

        if conf.mon_int_range is None:
            start_val = float("inf")
            end_val = float("inf")
        else:
            start_val = conf.mon_int_range[0]
            end_val = conf.mon_int_range[1]

        dm_som2 = dr_lib.integrate_spectra(dm_som1,
                                           start=start_val,
                                           end=end_val,
                                           width=True)
        if t is not None:
            t.getTime(msg="After integrating upstream monitor spectrum ")
    else:
        dm_som2 = dm_som1

    del dm_som1

    tib_norm_const = None

    # Step 4: Divide data set by summed monitor spectrum
    if dm_som2 is not None:
        if conf.verbose:
            print "Normalizing %s by monitor sum" % dataset_type

        if t is not None:
            t.getTime(False)

        dp_som2 = common_lib.div_ncerr(dp_som1, dm_som2, length_one_som=True)

        tib_norm_const = dm_som2[0].y

        if t is not None:
            t.getTime(msg="After normalizing %s by monitor sum" % dataset_type)

    elif conf.pc_norm:
        if conf.verbose:
            print "Normalizing %s by proton charge" % dataset_type

        pc_tag = dataset_type + "-proton_charge"
        pc = dp_som1.attr_list[pc_tag]

        # Scale the proton charge and then set the scale PC back to attributes
        if conf.scale_pc is not None:
            if conf.verbose:
                print "Scaling %s proton charge" % dataset_type

            pc = hlr_utils.scale_proton_charge(pc, conf.scale_pc)
            dp_som1.attr_list[pc_tag] = pc

        tib_norm_const = pc.getValue()

        if t is not None:
            t.getTime(False)

        dp_som2 = common_lib.div_ncerr(dp_som1, (pc.getValue(), 0.0))

        if t is not None:
            t.getTime(msg="After normalizing %s by proton charge" \
                      % dataset_type)

    else:
        dp_som2 = dp_som1

    del dp_som1, dm_som2

    # Step 5: Scale dark current by data set measurement time
    if dkcur is not None:
        if conf.verbose:
            print "Scaling dark current by %s acquisition time" % dataset_type

        if t is not None:
            t.getTime(False)

        dstime_tag = dataset_type + "-duration"
        dstime = dp_som2.attr_list[dstime_tag]

        dkcur1 = common_lib.div_ncerr(dkcur, (dstime.getValue(), 0.0))

        if t is not None:
            t.getTime(msg="After scaling dark current by %s acquisition time" \
                      % dataset_type)
    else:
        dkcur1 = dkcur

    del dkcur

    # Step 6: Subtract scaled dark current from data set
    if dkcur1 is not None:
        if conf.verbose:
            print "Subtracting %s by scaled dark current" % dataset_type

        if t is not None:
            t.getTime(False)

        dp_som3 = common_lib.sub_ncerr(dp_som2, dkcur1)

        if t is not None:
            t.getTime(msg="After subtracting %s by scaled dark current" \
                      % dataset_type)
    elif tib_const is not None and dkcur1 is None:
        if conf.verbose:
            print "Subtracting TIB constant from %s" % dataset_type

        # Normalize the TIB constant by dividing by the current normalization
        # the duration (if necessary) and the conversion from seconds to
        # microseconds
        tib_c = tib_const.toValErrTuple()

        conv_sec_to_usec = 1.0e-6

        if tib_norm_const is None:
            tib_norm_const = 1
            duration = 1
        else:
            duration_tag = dataset_type + "-duration"
            duration = dp_som2.attr_list[duration_tag].getValue()

        norm_const = (duration * conv_sec_to_usec) / tib_norm_const

        tib_val = tib_c[0] * norm_const
        tib_err2 = tib_c[1] * (norm_const * norm_const)

        if t is not None:
            t.getTime(False)

        dp_som3 = common_lib.sub_ncerr(dp_som2, (tib_val, tib_err2))

        if t is not None:
            t.getTime(msg="After subtracting TIB constant from %s" \
                      % dataset_type)
    elif conf.tib_range is not None and dkcur1 is None:
        if conf.verbose:
            print "Determining TIB constant from %s" % dataset_type

        if t is not None:
            t.getTime(False)

        TIB = dr_lib.determine_time_indep_bkg(dp_som2,
                                              conf.tib_range,
                                              is_range=True)

        if t is not None:
            t.getTime(msg="After determining TIB constant from %s" \
                      % dataset_type)

        if conf.dump_tib:
            file_comment = "TIB TOF Range: [%d, %d]" % (conf.tib_range[0],
                                                        conf.tib_range[1])

            hlr_utils.write_file(conf.output, "text/num-info", TIB,
                                 output_ext="tib",
                                 extra_tag=dataset_type,
                                 verbose=conf.verbose,
                                 data_ext=conf.ext_replacement,
                                 path_replacement=conf.path_replacement,
                                 message="time-independent background "\
                                 +"information",
                                 tag="Average TIB",
                                 units="counts/usec",
                                 comments=[file_comment])

        if conf.verbose:
            print "Subtracting TIB constant from %s" % dataset_type

        if t is not None:
            t.getTime(False)

        dp_som3 = common_lib.sub_ncerr(dp_som2, TIB)

        if t is not None:
            t.getTime(msg="After subtracting TIB constant from %s" \
                      % dataset_type)

        del TIB
    else:
        dp_som3 = dp_som2

    del dp_som2, dkcur1

    if conf.dump_ctof_comb:
        dp_som3_1 = dr_lib.sum_all_spectra(dp_som3)
        hlr_utils.write_file(conf.output,
                             "text/Spec",
                             dp_som3_1,
                             output_ext="ctof",
                             extra_tag=dataset_type,
                             data_ext=conf.ext_replacement,
                             path_replacement=conf.path_replacement,
                             verbose=conf.verbose,
                             message="combined calibrated TOF information")

        del dp_som3_1

    return dp_som3
예제 #3
0
def process_dgs_data(obj, conf, bcan, ecan, tcoeff, **kwargs):
    """
    This function combines Steps 7 through 16 in Section 2.1.1 of the data
    reduction process for Direct Geometry Spectrometers as specified by the
    document at 
    U{http://neutrons.ornl.gov/asg/projects/SCL/reqspec/DR_Lib_RS.doc}. The
    function takes a calibrated dataset, a L{hlr_utils.Configure} object and
    processes the data accordingly.

    @param obj: A calibrated dataset object.
    @type obj: C{SOM.SOM}

    @param conf: Object that contains the current setup of the driver.
    @type conf: L{hlr_utils.Configure}

    @param bcan: The object containing the black can data.
    @type bcan: C{SOM.SOM}

    @param ecan: The object containing the empty can data.
    @type ecan: C{SOM.SOM}

    @param tcoeff: The transmission coefficient appropriate to the given data
                   set.
    @type tcoeff: C{tuple}
    
    @param kwargs: A list of keyword arguments that the function accepts:

    @keyword dataset_type: The practical name of the dataset being processed.
                           The default value is I{data}.
    @type dataset_type: C{string}

    @keyword cwp_used: A flag signalling the use of the chopper phase
                       corrections.
    @type cwp_used: C{bool}

    @keyword timer: Timing object so the function can perform timing estimates.
    @type timer: C{sns_timer.DiffTime}


    @return: Object that has undergone all requested processing steps
    @rtype: C{SOM.SOM}
    """
    import array_manip
    import common_lib
    import dr_lib
    import hlr_utils

    # Check keywords
    try:
        dataset_type = kwargs["dataset_type"]
    except KeyError:
        dataset_type = "data"

    try:
        t = kwargs["timer"]
    except KeyError:
        t = None

    cwp_used = kwargs.get("cwp_used", False)

    if conf.verbose:
        print "Processing %s information" % dataset_type

    # Step 7: Create black can background contribution
    if bcan is not None:
        if conf.verbose:
            print "Creating black can background contribution for %s" \
                  % dataset_type

        if t is not None:
            t.getTime(False)

        bccoeff = array_manip.sub_ncerr(1.0, 0.0, tcoeff[0], tcoeff[1])
        bcan1 = common_lib.mult_ncerr(bcan, bccoeff)

        if t is not None:
            t.getTime(msg="After creating black can background contribution ")

        del bcan
    else:
        bcan1 = None

    # Step 8: Create empty can background contribution
    if ecan is not None:
        if conf.verbose:
            print "Creating empty can background contribution for %s" \
                  % dataset_type

        if t is not None:
            t.getTime(False)

        ecan1 = common_lib.mult_ncerr(ecan, tcoeff)

        if t is not None:
            t.getTime(msg="After creating empty can background contribution ")

        del ecan
    else:
        ecan1 = None

    # Step 9: Create background spectra
    if bcan1 is not None or ecan1 is not None and conf.verbose:
        print "Creating background spectra for %s" % dataset_type

    if bcan1 is not None and ecan1 is not None:
        if cwp_used:
            if conf.verbose:
                print "Rebinning empty can to black can axis."

            ecan2 = common_lib.rebin_axis_1D_frac(ecan1, bcan1[0].axis[0].val)
        else:
            ecan2 = ecan1

        del ecan1

        if t is not None:
            t.getTime(False)

        b_som = common_lib.add_ncerr(bcan1, ecan2)

        if t is not None:
            t.getTime(msg="After creating background spectra ")
    elif bcan1 is not None and ecan1 is None:
        b_som = bcan1
    elif bcan1 is None and ecan1 is not None:
        b_som = ecan1
    else:
        b_som = None

    del bcan1, ecan1

    if cwp_used:
        if conf.verbose:
            print "Rebinning background spectra to %s" % dataset_type

        b_som1 = common_lib.rebin_axis_1D_frac(b_som, obj[0].axis[0].val)
    else:
        b_som1 = b_som

    del b_som

    if conf.dump_ctof_comb and b_som1 is not None:
        b_som_1 = dr_lib.sum_all_spectra(b_som1)
        hlr_utils.write_file(conf.output,
                             "text/Spec",
                             b_som_1,
                             output_ext="ctof",
                             extra_tag="background",
                             data_ext=conf.ext_replacement,
                             path_replacement=conf.path_replacement,
                             verbose=conf.verbose,
                             message="combined background TOF information")
        del b_som_1

    # Step 10: Subtract background from data
    obj1 = dr_lib.subtract_bkg_from_data(obj,
                                         b_som1,
                                         verbose=conf.verbose,
                                         timer=t,
                                         dataset1=dataset_type,
                                         dataset2="background")

    del obj, b_som1

    # Step 11: Calculate initial velocity
    if conf.verbose:
        print "Calculating initial velocity"

    if t is not None:
        t.getTime(False)

    if conf.initial_energy is not None:
        initial_wavelength = common_lib.energy_to_wavelength(\
            conf.initial_energy.toValErrTuple())
        initial_velocity = common_lib.wavelength_to_velocity(\
            initial_wavelength)
    else:
        # This should actually calculate it, but don't have a way right now
        pass

    if t is not None:
        t.getTime(msg="After calculating initial velocity ")

    # Step 12: Calculate the time-zero offset
    if conf.time_zero_offset is not None:
        time_zero_offset = conf.time_zero_offset.toValErrTuple()
    else:
        # This should actually calculate it, but don't have a way right now
        time_zero_offset = (0.0, 0.0)

    # Step 13: Convert time-of-flight to final velocity
    if conf.verbose:
        print "Converting TOF to final velocity DGS"

    if t is not None:
        t.getTime(False)

    obj2 = common_lib.tof_to_final_velocity_dgs(obj1,
                                                initial_velocity,
                                                time_zero_offset,
                                                units="microsecond")

    if t is not None:
        t.getTime(msg="After calculating TOF to final velocity DGS ")

    del obj1

    # Step 14: Convert final velocity to final wavelength
    if conf.verbose:
        print "Converting final velocity DGS to final wavelength"

    if t is not None:
        t.getTime(False)

    obj3 = common_lib.velocity_to_wavelength(obj2)

    if t is not None:
        t.getTime(msg="After calculating velocity to wavelength ")

    del obj2

    if conf.dump_wave_comb:
        obj3_1 = dr_lib.sum_all_spectra(
            obj3, rebin_axis=conf.lambda_bins.toNessiList())
        hlr_utils.write_file(conf.output,
                             "text/Spec",
                             obj3_1,
                             output_ext="fwv",
                             extra_tag=dataset_type,
                             data_ext=conf.ext_replacement,
                             path_replacement=conf.path_replacement,
                             verbose=conf.verbose,
                             message="combined final wavelength information")

        del obj3_1

    # Step 15: Create the detector efficiency
    if conf.det_eff is not None:
        if conf.verbose:
            print "Creating detector efficiency spectra"

        if t is not None:
            t.getTime(False)

        det_eff = dr_lib.create_det_eff(obj3)

        if t is not None:
            t.getTime(msg="After creating detector efficiency spectra ")
    else:
        det_eff = None

    # Step 16: Divide the detector pixel spectra by the detector efficiency
    if det_eff is not None:
        if conf.verbose:
            print "Correcting %s for detector efficiency" % dataset_type

        if t is not None:
            t.getTime(False)

        obj4 = common_lib.div_ncerr(obj3, det_eff)

        if t is not None:
            t.getTime(msg="After correcting %s for detector efficiency" \
                      % dataset_type)
    else:
        obj4 = obj3

    del obj3, det_eff

    return obj4
예제 #4
0
def process_dgs_data(obj, conf, bcan, ecan, tcoeff, **kwargs):
    """
    This function combines Steps 7 through 16 in Section 2.1.1 of the data
    reduction process for Direct Geometry Spectrometers as specified by the
    document at 
    U{http://neutrons.ornl.gov/asg/projects/SCL/reqspec/DR_Lib_RS.doc}. The
    function takes a calibrated dataset, a L{hlr_utils.Configure} object and
    processes the data accordingly.

    @param obj: A calibrated dataset object.
    @type obj: C{SOM.SOM}

    @param conf: Object that contains the current setup of the driver.
    @type conf: L{hlr_utils.Configure}

    @param bcan: The object containing the black can data.
    @type bcan: C{SOM.SOM}

    @param ecan: The object containing the empty can data.
    @type ecan: C{SOM.SOM}

    @param tcoeff: The transmission coefficient appropriate to the given data
                   set.
    @type tcoeff: C{tuple}
    
    @param kwargs: A list of keyword arguments that the function accepts:

    @keyword dataset_type: The practical name of the dataset being processed.
                           The default value is I{data}.
    @type dataset_type: C{string}

    @keyword cwp_used: A flag signalling the use of the chopper phase
                       corrections.
    @type cwp_used: C{bool}

    @keyword timer: Timing object so the function can perform timing estimates.
    @type timer: C{sns_timer.DiffTime}


    @return: Object that has undergone all requested processing steps
    @rtype: C{SOM.SOM}
    """
    import array_manip
    import common_lib
    import dr_lib
    import hlr_utils

    # Check keywords
    try:
        dataset_type = kwargs["dataset_type"]
    except KeyError:
        dataset_type = "data"

    try:
        t = kwargs["timer"]
    except KeyError:
        t = None

    cwp_used = kwargs.get("cwp_used", False)
        
    if conf.verbose:
        print "Processing %s information" % dataset_type

    # Step 7: Create black can background contribution
    if bcan is not None:
        if conf.verbose:
            print "Creating black can background contribution for %s" \
                  % dataset_type

        if t is not None:
            t.getTime(False)
            
        bccoeff = array_manip.sub_ncerr(1.0, 0.0, tcoeff[0], tcoeff[1])
        bcan1 = common_lib.mult_ncerr(bcan, bccoeff)

        if t is not None:
            t.getTime(msg="After creating black can background contribution ")
        
        del bcan
    else:
        bcan1 = None

    # Step 8: Create empty can background contribution
    if ecan is not None:
        if conf.verbose:
            print "Creating empty can background contribution for %s" \
                  % dataset_type

        if t is not None:
            t.getTime(False)
        
        ecan1 = common_lib.mult_ncerr(ecan, tcoeff)

        if t is not None:
            t.getTime(msg="After creating empty can background contribution ")
        
        del ecan
    else:
        ecan1 = None

    # Step 9: Create background spectra
    if bcan1 is not None or ecan1 is not None and conf.verbose:
        print "Creating background spectra for %s" % dataset_type
    
    if bcan1 is not None and ecan1 is not None:
        if cwp_used:
            if conf.verbose:
                print "Rebinning empty can to black can axis."
                
            ecan2 = common_lib.rebin_axis_1D_frac(ecan1, bcan1[0].axis[0].val)
        else:
            ecan2 = ecan1

        del ecan1
        
        if t is not None:
            t.getTime(False)

        b_som = common_lib.add_ncerr(bcan1, ecan2)

        if t is not None:
            t.getTime(msg="After creating background spectra ")
    elif bcan1 is not None and ecan1 is None:
        b_som = bcan1
    elif bcan1 is None and ecan1 is not None:
        b_som = ecan1
    else:
        b_som = None

    del bcan1, ecan1

    if cwp_used:
        if conf.verbose:
            print "Rebinning background spectra to %s" % dataset_type

        b_som1 = common_lib.rebin_axis_1D_frac(b_som, obj[0].axis[0].val)
    else:
        b_som1 = b_som

    del b_som

    if conf.dump_ctof_comb and b_som1 is not None:
        b_som_1 = dr_lib.sum_all_spectra(b_som1)
        hlr_utils.write_file(conf.output, "text/Spec", b_som_1,
                             output_ext="ctof",
                             extra_tag="background",
                             data_ext=conf.ext_replacement,    
                             path_replacement=conf.path_replacement,
                             verbose=conf.verbose,
                             message="combined background TOF information")
        del b_som_1
        
    # Step 10: Subtract background from data
    obj1 = dr_lib.subtract_bkg_from_data(obj, b_som1, verbose=conf.verbose,
                                         timer=t,
                                         dataset1=dataset_type,
                                         dataset2="background")

    del obj, b_som1

    # Step 11: Calculate initial velocity
    if conf.verbose:
        print "Calculating initial velocity"

    if t is not None:
        t.getTime(False)
        
    if conf.initial_energy is not None:
        initial_wavelength = common_lib.energy_to_wavelength(\
            conf.initial_energy.toValErrTuple())
        initial_velocity = common_lib.wavelength_to_velocity(\
            initial_wavelength)
    else:
        # This should actually calculate it, but don't have a way right now
        pass

    if t is not None:
        t.getTime(msg="After calculating initial velocity ")

    # Step 12: Calculate the time-zero offset
    if conf.time_zero_offset is not None:
        time_zero_offset = conf.time_zero_offset.toValErrTuple()
    else:
        # This should actually calculate it, but don't have a way right now
        time_zero_offset = (0.0, 0.0)

    # Step 13: Convert time-of-flight to final velocity
    if conf.verbose:
        print "Converting TOF to final velocity DGS"

    if t is not None:
        t.getTime(False)
        
    obj2 = common_lib.tof_to_final_velocity_dgs(obj1, initial_velocity,
                                                time_zero_offset,
                                                units="microsecond")

    if t is not None:
        t.getTime(msg="After calculating TOF to final velocity DGS ")
        
    del obj1
    
    # Step 14: Convert final velocity to final wavelength
    if conf.verbose:
        print "Converting final velocity DGS to final wavelength"

    if t is not None:
        t.getTime(False)
        
    obj3 = common_lib.velocity_to_wavelength(obj2)

    if t is not None:
        t.getTime(msg="After calculating velocity to wavelength ")

    del obj2

    if conf.dump_wave_comb:
        obj3_1 = dr_lib.sum_all_spectra(obj3,
                                     rebin_axis=conf.lambda_bins.toNessiList())
        hlr_utils.write_file(conf.output, "text/Spec", obj3_1,
                             output_ext="fwv",
                             extra_tag=dataset_type,
                             data_ext=conf.ext_replacement,    
                             path_replacement=conf.path_replacement,
                             verbose=conf.verbose,
                             message="combined final wavelength information")

        del obj3_1

    # Step 15: Create the detector efficiency
    if conf.det_eff is not None:
        if conf.verbose:
            print "Creating detector efficiency spectra"

        if t is not None:
            t.getTime(False)
            
        det_eff = dr_lib.create_det_eff(obj3)

        if t is not None:
            t.getTime(msg="After creating detector efficiency spectra ")
    else:
        det_eff = None

    # Step 16: Divide the detector pixel spectra by the detector efficiency
    if det_eff is not None:
        if conf.verbose:
            print "Correcting %s for detector efficiency" % dataset_type

        if t is not None:
            t.getTime(False)

        obj4 = common_lib.div_ncerr(obj3, det_eff)

        if t is not None:
            t.getTime(msg="After correcting %s for detector efficiency" \
                      % dataset_type)
    else:
        obj4 = obj3

    del obj3, det_eff

    return obj4