#!/usr/bin/env python
##################################################
# Example.py
# Maintained by G.Winter
# 3rd March 2003
# 
# 
# A test for the interface - and a long and documented
# example for how to use the interface
# 
# NB. The data for this example can be downloaded, as
# either a tar file, or as an iso9660 cd image - links 
# are available from the index page above...
# 
# 
# 
# 
# 
# $Id: Example.html,v 1.2 2003/03/05 11:52:18 gwin Exp $
##################################################

# import a few system things -
# sys needed to access sys.path
# re needed for processing the templates to directory names
# os to give os.mkdir, to make a working directory

import sys, re, os

import MosflmInterface

# add the xsd stuff to the path, so that we can access all of the
# DNA objects - this should perhaps use os.environ("DNA_HOME")

sys.path.append("/home/graeme/noddy/xsd/python")

# import the XSD module
import XSD

# set the data directory - in this instace we have all of the test
# images in the one directory
directory = "/data/graeme/ESRF/DNA-6Dec02/TestSet"

# and here are a list of templates for the test images - there are 21 pairs
# of images
templateList = ["DNA_1_###.img",
                "dntr_3_###.img",
                "dntr_9_###.img",
                "gitest_4_###.img",
                "DNA_2_###.img",
                "dntr_4_###.img",
                "ferritin_1_###.img",
                "mystery_1_###.img",
                "DNA_3_###.img",
                "dntr_5_###.img",
                "ferritin_2_###.img",
                "mystery_2_###.img",
                "DNA_4_###.img",
                "dntr_6_###.img",
                "ferritin_3_###.img",
                "dntr_1_###.img",
                "dntr_7_###.img",
                "gitest_1_###.img",
                "dntr_2_###.img",
                "dntr_8_###.img",
                "gitest_2_###.img"]

# This sets the output file, where the mosflm output will be sent, and
# will be persistant. Further, the mosflm output will always be appended.
MosflmInterface.SetMosflmInterfaceFile("fluffy-bunny.out")

# Set the mosflm instance that we wish to use for this processing -
# this could perhaps use os.environ("CCP4")/bin/ipmosflm
# to use the standard "vanilla" CCP4 distributed mosflm
# (Not advised! :oD)

MosflmInterface.SetMosflmExecutable("/home/graeme/mosflm-gui/mosflm/bin/ipmosflm")

# now loop over the templates, processing 1, 2, 1 + 2 images

for template in templateList:

    # keep us happy in the knowledge that there is something going on
    print "Testing with template " + str(template)
    
    # make a place to store things. - and create a working directory
    # perhaps this regular expression could go outside, but I don't
    # think that this will be a killer on the performance stakes!
    
    regexp = re.compile(r'(.*)_(\#*)\.(.*)')
    match = regexp.match(template)
    # this gets the beginning of the template - the bit up to ###
    firstImagePrefix = match.group(1)
    path = "/emergency/graeme/processing/Mosflm_" + firstImagePrefix

    # given that we're processing three batches of images per template,
    # it would be tidy to keep these separate
    for extra in ["1", "2", "12"]:
        try:
            os.mkdir(path + extra)
        except OSError, message:
            print message

    # here's out input xml documents - which will have the image lists and
    # templates written into them - in the real example these might come
    # through the sockets on the wings of a HTTP packet
    xml1 = "<?xml version='1.0'?><!DOCTYPE index_request>" + \
           "<index_request><target><symmetry></symmetry>" + \
           "<cell><a></a><b></b><c></c><alpha></alpha><beta></beta>" + \
           "<gamma></gamma></cell></target><experiment><wavelength>" + \
           "</wavelength><distance></distance></experiment>" + \
           "<fileinfo><template>" + \
           template + \
           "</template><directory>" + \
           directory + \
           "</directory><matrix_file></matrix_file></fileinfo>" + \
           "<detector><type>adsc</type></detector><beam><x>93.63</x>" + \
           "<y>95.19</y></beam><image>1</image></index_request>"

    xml2 = "<?xml version='1.0'?><!DOCTYPE index_request>" + \
           "<index_request><target><symmetry></symmetry>" + \
           "<cell><a></a><b></b><c></c><alpha></alpha><beta></beta>" + \
           "<gamma></gamma></cell></target><experiment><wavelength>" + \
           "</wavelength><distance></distance></experiment>" + \
           "<fileinfo><template>" + \
           template + \
           "</template><directory>" + \
           directory + \
           "</directory><matrix_file></matrix_file></fileinfo>" + \
           "<detector><type>adsc</type></detector><beam><x>93.63</x>" + \
           "<y>95.19</y></beam><image>2</image></index_request>"

    xml12 = "<?xml version='1.0'?><!DOCTYPE index_request>" + \
           "<index_request><target><symmetry></symmetry>" + \
           "<cell><a></a><b></b><c></c><alpha></alpha><beta></beta>" + \
           "<gamma></gamma></cell></target><experiment><wavelength>" + \
           "</wavelength><distance></distance></experiment>" + \
           "<fileinfo><template>" + \
           template + \
           "</template><directory>" + \
           directory + \
           "</directory><matrix_file></matrix_file></fileinfo>" + \
           "<detector><type>adsc</type></detector><beam><x>93.63</x>" + \
           "<y>95.19</y></beam><image>1</image><image>2</image>" + \
           "</index_request>"

    # create three Index_request objects to keep this information in.
    index_request1 = XSD.Index_request()
    index_request2 = XSD.Index_request()
    index_request12 = XSD.Index_request()
    
    # this shouldn't be a method... indeed it should be XSD.XMLStringToDict().
    # because it doesn't make use of the class instance data. -> change this
    dict = index_request1.XMLStringToDict(xml1)
    index_request1.fromDict(dict["index_request"])

    dict = index_request2.XMLStringToDict(xml2)
    index_request2.fromDict(dict["index_request"])

    dict = index_request12.XMLStringToDict(xml12)
    index_request12.fromDict(dict["index_request"])

    # perform the three index requests - performing 1 last
    # because I will want the matrices from that one...

    # every time you RestartMosflm, you need to SetWorkingDirectory -
    # because it is unlikely you will want a persistant working directory
    MosflmInterface.RestartMosflm(3)
    MosflmInterface.SetWorkingDirectory(path + "2")

    # 2
    index_response2 = MosflmInterface.do_index_request(index_request2, 1)
    d2 = { }
    d2["index_response"] = index_response2.toDict()
    print index_response2.DictToXML(d2)

    MosflmInterface.RestartMosflm(3)
    MosflmInterface.SetWorkingDirectory(path + "12")

    # 1 + 2
    index_response12 = MosflmInterface.do_index_request(index_request12, 1)
    d12 = { }
    d12["index_response"] = index_response12.toDict()
    print index_response2.DictToXML(d12)

    MosflmInterface.RestartMosflm(3)
    MosflmInterface.SetWorkingDirectory(path + "1")

    # 1
    index_response1 = MosflmInterface.do_index_request(index_request1, 1)
    d1 = { }
    d1["index_response"] = index_response1.toDict()
    print index_response1.DictToXML(d1)

    # this is going to produce a rather excessive amount of data - is there
    # perhaps a way to condense it all? - will want to write some
    # SolutionComparison routines.
    
    # check that we have indexed okay - this is only looking at the
    # results from indexing image 1
    if d1["index_response"]["status"]["code"] != "ok":
        # warn the client
        print "Indexing failed!"
        print index_response1.DictToXML(d1)
    else:
        # continue - and get the mosaicity, strategy and integration
        # information
        print index_response1.DictToXML(d1)
        
        xml = "<?xml version='1.0'?>" + \
              "<!DOCTYPE mosaicity_request><mosaicity_request/>"
        
        mosaicity_request = XSD.Mosaicity_request()
        dict  = mosaicity_request.XMLStringToDict(xml)
        mosaicity_request.fromDict(dict["mosaicity_request"])
        mosaicity_response = \
                           MosflmInterface.do_mosaicity_request(mosaicity_request)
        d = { }
        d["mosaicity_response"] = mosaicity_response.toDict()
        
        print mosaicity_response.DictToXML(d)
        
        # this has changed, but the lower resolution limit should be optional!
        # and meaningless! I have chosen 2 Angstroms for no adequately
        # eplained reason.
        
        xml = "<?xml version='1.0'?><!DOCTYPE strategy_request>" + \
              "<strategy_request><strategy_settings><resolution_limits>" + \
              "<upper><isotropic>2</isotropic></upper><lower>" + \
              "<isotropic>2</isotropic></lower></resolution_limits>" + \
              "</strategy_settings></strategy_request>"

        # Create a strategy request
        strategy_request = XSD.Strategy_request()

        # and populate it
        dict  = strategy_request.XMLStringToDict(xml)
        strategy_request.fromDict(dict["strategy_request"])
        strategy_response = MosflmInterface.do_strategy_request(strategy_request)
        
        d = { }
        d["strategy_response"] = strategy_response.toDict()
        
        print strategy_response.DictToXML(d)
        
        xml = "<?xml version='1.0'?><!DOCTYPE single_integrate_request>" + \
              "<single_integrate_request><image>1</image>" + \
              "</single_integrate_request>"

        # and create a single_integrate_request
        single_integrate_request = XSD.Single_integrate_request()

        # and populate that
        dict = single_integrate_request.XMLStringToDict(xml)
        single_integrate_request.fromDict(dict["single_integrate_request"])
        
        single_integrate_response = \
                                  MosflmInterface.do_single_integrate_request(single_integrate_request)
        d = { }
        d["single_integrate_response"] = single_integrate_response.toDict()
        print single_integrate_response.DictToXML(d)
        
        # here endeth the loop