
#/*##########################################################################
# Copyright (C) 2001-2013 European Synchrotron Radiation Facility
#
#              PyHST2  
#  European Synchrotron Radiation Facility, Grenoble,France
#
# PyHST2 is  developed at
# the ESRF by the Scientific Software  staff.
# Principal author for PyHST2: Alessandro Mirone.
#
# This program is free software; you can redistribute it and/or modify it 
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option) 
# any later version.
#
# PyHST2 is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# PyHST2; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307, USA.
#
# PyHST2 follows the dual licensing model of Trolltech's Qt and Riverbank's PyQt
# and cannot be used as a free plugin for a non-free program. 
#
# Please contact the ESRF industrial unit (industry@esrf.fr) if this license 
# is a problem for you.
#############################################################################*/


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function



import mpi4py.MPI as MPI
myrank = MPI.COMM_WORLD.Get_rank()
import os

def Check_must_have_keys(dizio, keys, optionals):
    if(  set(dizio.keys())!=set(keys) ):
        diff = set(dizio.keys())-set(keys)
        if not (diff<=set(optionals)):
            print( " ############### " )
            B = keys
            A = dizio.keys()
            for a in A:
                if a not in optionals:
                    print( a , a in B)
            print( " ################ " )
            raise Exception(  " set(dizio.keys())!=set(keys)  ")

from . import Parameters_module

ncpus  =  Parameters_module.ncpus
print( " process " , myrank, " mygpus = " , Parameters_module.mygpus)

if Parameters_module.mygpus!=[]:
    Parameters_module.Parameters.MYGPU=  Parameters_module.mygpus[0]
else:
    Parameters_module.Parameters.MYGPU= -1

if Parameters_module.Parameters.MYGPU== -1:
    Parameters_module.Parameters.TRYGPU=0

#     import cudadistribution as cudadistribution
#     res=cudadistribution.cudadistribute(1,1,)
#     print( " Process ", myrank," has chose card ", res  )


proj_reading_dict = Parameters_module.get_proj_reading()


Check_must_have_keys(proj_reading_dict ,["proj_reading_type","proj_file_list","corr_file_list","my_proj_num_list","tot_proj_num_list","file_proj_num_list","ff_file_list",
                                         "ff_indexes_coefficients","proj_mpi_offsets","proj_mpi_numpjs","pos_s","size_s","pos_s_","size_s_",
                                         "slices_mpi_numslices","slices_mpi_offsets" ,"ff_reading_type", "proj_num_offset_list","NUM_LAST_IMAGE","allfile_list"
                                         ],
                     ["proj_h5_dsname","ff_h5_dsname"])


arrays_space_in_python = Parameters_module.create_arrays_space_as_dictionary(proj_reading_dict)
Check_must_have_keys( arrays_space_in_python, ["ff_rawdatatokens","rawdatatokens", "datatokens"
                                               ,"transposeddatatokens","background","doubleffcorrection","patches"] , [])


dirname=os.path.dirname(os.path.abspath(__file__))

from . import Cspace
print( " chiamo Cspace " , dirname)

print( Parameters_module.Parameters.CONICITY_MARGIN_UP)
P=Parameters_module.Parameters



# Sirt-Filter
if P.SF_ITERATIONS:
    try:
        import astra
    except ImportError:
        raise Exception("Error loading astra. Please install the astra toolbox with its python binding to use the SIRT-Filter")
    try:
        from .tomography import AstraToolbox
        from .sirtfilter import SirtFilter
    except ImportError:
        raise Exception("Could not import tomography.py or sirtfilter.py. Please make sure that they are available.")

    import numpy as np
    _PI_ = np.pi

    n_x = int(P.END_VOXEL_1 - P.START_VOXEL_1 +1)
    n_y = int(P.END_VOXEL_2 - P.START_VOXEL_2 +1)
    n_det = int(P.NUM_IMAGE_1)
    n_angles = int((P.NUM_LAST_IMAGE - P.NUM_FIRST_IMAGE +1)//P.FILE_INTERVAL)
    delta_angle = float(P.ANGLE_BETWEEN_PROJECTIONS * _PI_/180.)
    offset_angle = float(P.ANGLE_OFFSET * _PI_ /180.)
    rot_center = float(P.ROTATION_AXIS_POSITION)
    n_it = int(P.SF_ITERATIONS)
    Lambda = float(P.SF_LAMBDA)
    savedir = str(P.SF_FILTER_FILE)

    angles_astra = offset_angle + np.arange(n_angles)*delta_angle
    if not(os.path.isdir(savedir)):
        print(("Error: %s no such directory" % savedir))
        exit(1)

    if rot_center == 0: rot_center = None
    tomo = AstraToolbox(n_x, n_y, angles_astra, dwidth=n_det, rot_center=rot_center)

    print(("Computing filter with %d iterations, Lambda=%.2f" % (n_it, Lambda)))
    print(("(n_x, n_y) = (%d, %d), n_det = %d, n_angles = %d" % (n_x, n_y, n_det, n_angles)))
    SirtFilter = SirtFilter(tomo, n_it, savedir=savedir, lambda_tikhonov=Lambda, hdf5=True)
    P.SF_FILTER = SirtFilter.thefilter.ravel() # for cpyutils
# -------


cspace=Cspace.Cspace(  arrays_space_in_python ,  Parameters_module.Parameters , dirname )

if myrank==0: print( " going to configure readings ")
cspace.configure_readings( proj_reading_dict )
from . import Control
# mygpus is a list of integers
control=Control.Control( Parameters_module.Parameters,   cspace ,
                         ncpus, Parameters_module.mygpus,Parameters_module.Parameters.NPBUNCHES ,arrays_space_in_python  )
control.execute(Parameters_module.Postprocess)
MPI.COMM_WORLD.Barrier()


 
