def get_idf_path_from_workspace(workspace):
    """
    Gets the full IDF path from a workspace.

    It queries the workspace for the start time and instrument name. It gets the IDF path from the ExperimentInfo.
    :param workspace: the workspace for which we want the full IDF path.
    :return: the full IDF path for the instrument of the workspace.
    """
    run = workspace.run()
    instrument = workspace.getInstrument()
    instrument_name = instrument.getName()
    instrument_name = sanitise_instrument_name(instrument_name)
    if run.hasProperty("start_time"):
        time = run.getProperty("start_time").value
        idf_path = ExperimentInfo.getInstrumentFilename(instrument_name, time)
    elif run.hasProperty("run_start"):
        time = run.getProperty("run_start").value
        idf_path = ExperimentInfo.getInstrumentFilename(instrument_name, time)
    else:
        idf_path = None
    return idf_path
def get_idf_path_from_workspace(workspace):
    """
    Gets the full IDF path from a workspace.

    It queries the workspace for the start time and instrument name. It gets the IDF path from the ExperimentInfo.
    :param workspace: the workspace for which we want the full IDF path.
    :return: the full IDF path for the instrument of the workspace.
    """
    run = workspace.run()
    instrument = workspace.getInstrument()
    instrument_name = instrument.getName()
    instrument_name = sanitise_instrument_name(instrument_name)
    if run.hasProperty("start_time"):
        time = run.getProperty("start_time").value
        idf_path = ExperimentInfo.getInstrumentFilename(instrument_name, time)
    elif run.hasProperty("run_start"):
        time = run.getProperty("run_start").value
        idf_path = ExperimentInfo.getInstrumentFilename(instrument_name, time)
    else:
        idf_path = None
    return idf_path
def GetPixelSize():     # reads current IDF and get pixelsize from there
    """ To get pixel size for Bilby detectors from the Bilby_Definition.xml file """

    from mantid.api import ExperimentInfo
    import xml.etree.cElementTree as ET

    currentIDF = ExperimentInfo.getInstrumentFilename("Bilby")
    #print currentIDF
    tree = ET.parse(currentIDF)
    for node in tree.iter():
        if node.tag=="{http://www.mantidproject.org/IDF/1.0}height":
            name = node.attrib.get('val')
            break
    pixelsize = float(name)
  
    return pixelsize
def get_pixel_size():  # reads current IDF and get pixelsize from there
    """ To get pixel size for Bilby detectors from the Bilby_Definition.xml file """

    from mantid.api import ExperimentInfo
    import xml.etree.cElementTree as ET

    currentIDF = ExperimentInfo.getInstrumentFilename("Bilby")
    # print currentIDF
    tree = ET.parse(currentIDF)
    for node in tree.iter():
        if node.tag == "{http://www.mantidproject.org/IDF/1.0}height":
            name = node.attrib.get('val')
            break
    pixelsize = float(name)

    return pixelsize
Example #5
0
def get_instrument_paths_for_sans_file(file_name=None, file_information=None):
    """
    Gets the Instrument Definition File (IDF) path and the Instrument Parameter Path (IPF) path associated with a file.

    :param file_name: the file name is a name fo a SANS data file, e.g. SANS2D0001234. This or the file_information
                      has to be specified.
    :param file_information: a file_information object. either this or the file_name has to be specified.
    :return: the IDF path and the IPF path
    """
    def get_file_location(path):
        return os.path.dirname(path)

    def get_ipf_equivalent_name(path):
        # If XXX_Definition_Yyy.xml is the IDF name, then the equivalent  IPF name is: XXX_Parameters_Yyy.xml
        base_file_name = os.path.basename(path)
        return base_file_name.replace(DEFINITION, PARAMETERS)

    def get_ipf_standard_name(path):
        # If XXX_Definition_Yyy.xml is the IDF name, then the standard IPF name is: XXX_Parameters.xml
        base_file_name = os.path.basename(path)
        elements = base_file_name.split("_")
        return elements[0] + PARAMETERS_XML_SUFFIX

    def check_for_files(directory, path):
        # Check if XXX_Parameters_Yyy.xml exists in the same folder
        ipf_equivalent_name = get_ipf_equivalent_name(path)
        ipf_equivalent = os.path.join(directory, ipf_equivalent_name)
        if os.path.exists(ipf_equivalent):
            return ipf_equivalent

        # Check if XXX_Parameters.xml exists in the same folder
        ipf_standard_name = get_ipf_standard_name(path)
        ipf_standard = os.path.join(directory, ipf_standard_name)
        if os.path.exists(ipf_standard):
            return ipf_standard
        # Does not seem to be in the folder
        return None

    def get_ipf_for_rule_1(path):
        # Check if can be found in the same folder
        directory = get_file_location(path)
        return check_for_files(directory, path)

    def get_ipf_for_rule_2(path):
        # Check if can be found in the instrument folder
        directory = ConfigService.getInstrumentDirectory()
        return check_for_files(directory, path)

    # Get the measurement date
    if not isinstance(file_information, SANSFileInformation):
        file_information_factory = SANSFileInformationFactory()
        file_information = file_information_factory.create_sans_file_information(
            file_name)
    measurement_time = file_information.get_date()

    # For some odd reason the __str__ method of DateAndTime adds a space which we need to strip here. It seems
    # to be on purpose though since the export method is called IS08601StringPlusSpace --> hence we need to strip it
    # ourselves
    measurement_time_as_string = str(measurement_time).strip()

    # Get the instrument
    instrument = file_information.get_instrument()
    instrument_as_string = instrument.value

    # Get the idf file path
    # IMPORTANT NOTE: I profiled the call to ExperimentInfo.getInstrumentFilename and it dominates
    #                 the state creation. Ironically this routine is exported from C++. The problem is
    #                 that we are performing XML parsing on the C++ side, which is costly. There is a
    #                 movement currently towards making the IDF redundant and storing instrument info
    #                 as native nexus information.
    # TODO for optimization: Add the IDF path to a global cache layer which takes the
    #                        instrument name and the from-to dates
    idf_path = ExperimentInfo.getInstrumentFilename(
        instrument_as_string, measurement_time_as_string)
    idf_path = os.path.normpath(idf_path)

    if not os.path.exists(idf_path):
        raise RuntimeError(
            "SANSFileInformation: The instrument definition file {0} does not seem to "
            "exist.".format(str(idf_path)))

    # Get the ipf path. This is slightly more complicated. See the Mantid documentation for the naming rules. Currently
    # they are:
    # 1. If the IDF is not in the instrument folder and there is another X_Parameters.xml in the same folder,
    #    this one in the same folder will be used instead of any parameter file in the instrument folder.
    # 2. If you want one parameter file for your IDF file, name your IDF file X_Definition_Yyy.xml and the parameter
    #    file X_Parameters_Yyy.xml , where Yyy is any combination a characters you find appropriate. If your IDF
    #    file is not in the instrument folder, the parameter file can be in either the same folder or in the instrument
    #    folder, but it can only be in the instrument folder, if the same folder has no X_Parameters.xml or
    #    X_Parameters_Yyy.xml file. If there is no X_Parameters_Yyy.xml file, X_Parameters.xml would be used.
    ipf_rule1 = get_ipf_for_rule_1(idf_path)
    if ipf_rule1:
        return idf_path, ipf_rule1

    ipf_rule2 = get_ipf_for_rule_2(idf_path)
    if ipf_rule2:
        return idf_path, ipf_rule2

    raise RuntimeError(
        "SANSFileInformation: There does not seem to be a corresponding instrument parameter file "
        "available for {0}".format(str(idf_path)))
Example #6
0
def get_instrument_paths_for_sans_file(file_name):
    """
    Gets the Instrument Definition File (IDF) path and the Instrument Parameter Path (IPF) path associated with a file.

    :param file_name: the file name is a name fo a SANS data file, e.g. SANS2D0001234
    :return: the IDF path and the IPF path
    """
    def get_file_location(path):
        return os.path.dirname(path)

    def get_ipf_equivalent_name(path):
        # If XXX_Definition_Yyy.xml is the IDF name, then the equivalent  IPF name is: XXX_Parameters_Yyy.xml
        base_file_name = os.path.basename(path)
        return base_file_name.replace("Definition", "Parameters")

    def get_ipf_standard_name(path):
        # If XXX_Definition_Yyy.xml is the IDF name, then the standard IPF name is: XXX_Parameters.xml
        base_file_name = os.path.basename(path)
        elements = base_file_name.split("_")
        return elements[0] + "_Parameters.xml"

    def check_for_files(directory, path):
        # Check if XXX_Parameters_Yyy.xml exists in the same folder
        ipf_equivalent_name = get_ipf_equivalent_name(path)
        ipf_equivalent = os.path.join(directory, ipf_equivalent_name)
        if os.path.exists(ipf_equivalent):
            return ipf_equivalent

        # Check if XXX_Parameters.xml exists in the same folder
        ipf_standard_name = get_ipf_standard_name(path)
        ipf_standard = os.path.join(directory, ipf_standard_name)
        if os.path.exists(ipf_standard):
            return ipf_standard
        # Does not seem to be in the folder
        return None

    def get_ipf_for_rule_1(path):
        # Check if can be found in the same folder
        directory = get_file_location(path)
        return check_for_files(directory, path)

    def get_ipf_for_rule_2(path):
        # Check if can be found in the instrument folder
        directory = ConfigService.getInstrumentDirectory()
        return check_for_files(directory, path)

    # Get the measurement date
    file_information_factory = SANSFileInformationFactory()
    file_information = file_information_factory.create_sans_file_information(file_name)
    measurement_time = file_information.get_date()
    # For some odd reason the __str__ method of DateAndTime adds a space which we need to strip here. It seems
    # to be on purpose though since the export method is called IS08601StringPlusSpace --> hence we need to strip it
    # ourselves
    measurement_time_as_string = str(measurement_time).strip()

    # Get the instrument
    instrument = file_information.get_instrument()
    instrument_as_string = SANSInstrument.to_string(instrument)

    # Get the idf file path
    idf_path = ExperimentInfo.getInstrumentFilename(instrument_as_string, measurement_time_as_string)
    idf_path = os.path.normpath(idf_path)

    if not os.path.exists(idf_path):
        raise RuntimeError("SANSFileInformation: The instrument definition file {0} does not seem to "
                           "exist.".format(str(idf_path)))

    # Get the ipf path. This is slightly more complicated. See the Mantid documentation for the naming rules. Currently
    # they are:
    # 1. If the IDF is not in the instrument folder and there is another X_Parameters.xml in the same folder,
    #    this one in the same folder will be used instead of any parameter file in the instrument folder.
    # 2. If you want one parameter file for your IDF file, name your IDF file X_Definition_Yyy.xml and the parameter
    #    file X_Parameters_Yyy.xml , where Yyy is any combination a characters you find appropriate. If your IDF
    #    file is not in the instrument folder, the parameter file can be in either the same folder or in the instrument
    #    folder, but it can only be in the instrument folder, if the same folder has no X_Parameters.xml or
    #    X_Parameters_Yyy.xml file. If there is no X_Parameters_Yyy.xml file, X_Parameters.xml would be used.
    ipf_rule1 = get_ipf_for_rule_1(idf_path)
    if ipf_rule1:
        return idf_path, ipf_rule1

    ipf_rule2 = get_ipf_for_rule_2(idf_path)
    if ipf_rule2:
        return idf_path, ipf_rule2

    raise RuntimeError("SANSFileInformation: There does not seem to be a corresponding instrument parameter file "
                       "available for {0}".format(str(idf_path)))
def get_instrument_paths_for_sans_file(file_name=None, file_information=None):
    """
    Gets the Instrument Definition File (IDF) path and the Instrument Parameter Path (IPF) path associated with a file.

    :param file_name: the file name is a name fo a SANS data file, e.g. SANS2D0001234. This or the file_information
                      has to be specified.
    :param file_information: a file_information object. either this or the file_name has to be specified.
    :return: the IDF path and the IPF path
    """
    def get_file_location(path):
        return os.path.dirname(path)

    def get_ipf_equivalent_name(path):
        # If XXX_Definition_Yyy.xml is the IDF name, then the equivalent  IPF name is: XXX_Parameters_Yyy.xml
        base_file_name = os.path.basename(path)
        return base_file_name.replace(DEFINITION, PARAMETERS)

    def get_ipf_standard_name(path):
        # If XXX_Definition_Yyy.xml is the IDF name, then the standard IPF name is: XXX_Parameters.xml
        base_file_name = os.path.basename(path)
        elements = base_file_name.split("_")
        return elements[0] + PARAMETERS_XML_SUFFIX

    def check_for_files(directory, path):
        # Check if XXX_Parameters_Yyy.xml exists in the same folder
        ipf_equivalent_name = get_ipf_equivalent_name(path)
        ipf_equivalent = os.path.join(directory, ipf_equivalent_name)
        if os.path.exists(ipf_equivalent):
            return ipf_equivalent

        # Check if XXX_Parameters.xml exists in the same folder
        ipf_standard_name = get_ipf_standard_name(path)
        ipf_standard = os.path.join(directory, ipf_standard_name)
        if os.path.exists(ipf_standard):
            return ipf_standard
        # Does not seem to be in the folder
        return None

    def get_ipf_for_rule_1(path):
        # Check if can be found in the same folder
        directory = get_file_location(path)
        return check_for_files(directory, path)

    def get_ipf_for_rule_2(path):
        # Check if can be found in the instrument folder
        directory = ConfigService.getInstrumentDirectory()
        return check_for_files(directory, path)

    # Get the measurement date
    if not isinstance(file_information, SANSFileInformation):
        file_information_factory = SANSFileInformationFactory()
        file_information = file_information_factory.create_sans_file_information(file_name)
    measurement_time = file_information.get_date()

    # For some odd reason the __str__ method of DateAndTime adds a space which we need to strip here. It seems
    # to be on purpose though since the export method is called IS08601StringPlusSpace --> hence we need to strip it
    # ourselves
    measurement_time_as_string = str(measurement_time).strip()

    # Get the instrument
    instrument = file_information.get_instrument()
    instrument_as_string = SANSInstrument.to_string(instrument)

    # Get the idf file path
    # IMPORTANT NOTE: I profiled the call to ExperimentInfo.getInstrumentFilename and it dominates
    #                 the state creation. Ironically this routine is exported from C++. The problem is
    #                 that we are performing XML parsing on the C++ side, which is costly. There is a
    #                 movement currently towards making the IDF redundant and storing instrument info
    #                 as native nexus information.
    # TODO for optimization: Add the IDF path to a global cache layer which takes the
    #                        instrument name and the from-to dates
    idf_path = ExperimentInfo.getInstrumentFilename(instrument_as_string, measurement_time_as_string)
    idf_path = os.path.normpath(idf_path)

    if not os.path.exists(idf_path):
        raise RuntimeError("SANSFileInformation: The instrument definition file {0} does not seem to "
                           "exist.".format(str(idf_path)))

    # Get the ipf path. This is slightly more complicated. See the Mantid documentation for the naming rules. Currently
    # they are:
    # 1. If the IDF is not in the instrument folder and there is another X_Parameters.xml in the same folder,
    #    this one in the same folder will be used instead of any parameter file in the instrument folder.
    # 2. If you want one parameter file for your IDF file, name your IDF file X_Definition_Yyy.xml and the parameter
    #    file X_Parameters_Yyy.xml , where Yyy is any combination a characters you find appropriate. If your IDF
    #    file is not in the instrument folder, the parameter file can be in either the same folder or in the instrument
    #    folder, but it can only be in the instrument folder, if the same folder has no X_Parameters.xml or
    #    X_Parameters_Yyy.xml file. If there is no X_Parameters_Yyy.xml file, X_Parameters.xml would be used.
    ipf_rule1 = get_ipf_for_rule_1(idf_path)
    if ipf_rule1:
        return idf_path, ipf_rule1

    ipf_rule2 = get_ipf_for_rule_2(idf_path)
    if ipf_rule2:
        return idf_path, ipf_rule2

    raise RuntimeError("SANSFileInformation: There does not seem to be a corresponding instrument parameter file "
                       "available for {0}".format(str(idf_path)))