
#/*##########################################################################
   # 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.
   #############################################################################*/
#undef NDEBUG
#include"Python.h"

#include "py3c.h"



#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include<time.h>
 
#include"structmember.h"
#include<string.h>
#include"CCspace.h"
#include"cpyutils.h"
#include<mpi.h>
#include <unistd.h>
#include <dlfcn.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

#define PY_ARRAY_UNIQUE_SYMBOL chst_ARRAY_API

#define cpyutils_PyArray1D_as_array(A,B,C) cpyutils_PyArray1D_as_array_TB( A,B,C, __FILE__, __LINE__ );
#define  cpyutils_o2i(A)  cpyutils_o2i_TB(A,  __FILE__, __LINE__  )
#define  cpyutils_o2f(A)  cpyutils_o2f_TB(A,  __FILE__, __LINE__  )
int cspace_iproc=0;

#include "numpy/arrayobject.h"
#define DEBUG(a)  if(cspace_iproc==0) printf("%s \n", a);
#undef NDEBUG
#include<hdf5.h>

herr_t my_hdf5_error_handler (void *unused)
{
   fprintf (stderr, "An HDF5 error was detected. Bye.\n");
   exit (1);
}


/*
 * The error object to expose
 */

static PyObject *ErrorObject;
#define onError(message)					\
  { PyErr_SetString(ErrorObject, message); return NULL;}


typedef struct {
  PyObject_HEAD
  CCspace *myCCspace;
  PyObject *OParameters ;
  PyObject *Orawdataarray ;
  PyObject *Off_rawdataarray ;
  PyObject *Offcorr ;
  PyObject *Obackground ;
  PyObject *Odataarray ;
  PyObject *Otransposeddataarray ;
  PyObject *Oaxis_corrections ;
  PyObject *Oaxis_correctionsL ;
  PyObject *Oangles ;
  PyObject *Iangles ;

  int iproc;
  int nprocs;
} Cspace;

static PyTypeObject Cspacetype;

static void
Cspace_dealloc(Cspace *self)
{
  DEBUG("... going to destroy a Cspace ...")
    CCspace_end(self->myCCspace); 

    Py_DECREF(self->Orawdataarray) ;
  Py_DECREF(self->Off_rawdataarray) ;
  Py_DECREF(self->Odataarray);
  Py_DECREF(self->Otransposeddataarray);
  Py_DECREF(self->Obackground);
  Py_DECREF(self->Oaxis_corrections);
  Py_DECREF(self->Oaxis_correctionsL);
  Py_DECREF(self->Offcorr);
  Py_DECREF(self->OParameters);

  CCspace_ffstatus_dealloc( self->myCCspace);

  if(self && 0 )
    free(self);
  DEBUG("... going to destroy a Cspace  ... OK")

    
    }

static PyObject *
Cspace_read_chunk( PyObject *self_a, PyObject *args)
{
  Cspace *self;
  int  sn, ntok, npbunches ;
  int rotation_vertical, binning ;
  int STEAM_DIRECTION;

  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;

  rotation_vertical = cpyutils_o2i(cpyutils_getattribute(self->OParameters ,"ROTATION_VERTICAL" )  );
  binning = cpyutils_o2i(cpyutils_getattribute(self->OParameters ,"BINNING" )  );

  if(!PyArg_ParseTuple(args,"iiii:Cspace_read_chunk", &sn, &ntok, &npbunches, &STEAM_DIRECTION))
    return NULL;
  /* sn  =cpyutils_o2i(Osn   ); */
  /* ntok=cpyutils_o2i(Ontok ); */
  Py_BEGIN_ALLOW_THREADS ;
  // sleep(1);
  if(STEAM_DIRECTION==1) {
    CCspace_read_chunk   ( self->myCCspace ,sn,  ntok , npbunches, rotation_vertical, binning ,0,0,0,0  );
  }

  Py_END_ALLOW_THREADS  ;
  // printf("esco da  Cspace_read_chunk \n");
  Py_INCREF( Py_None);
  return Py_None;
}


// C.tranpose_chunk(psn, ntoktreated, ntoktransposed, NPBUNCHES )
static PyObject *
Cspace_transpose_chunk( PyObject *self_a, PyObject *args)
{
  Cspace *self;

  int  sn,ntoktreated, ntoktransposed , npbunches ;
  int STEAM_DIRECTION;

  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;


  if(!PyArg_ParseTuple(args,"iiiii:Cspace_read_chunk", &sn,&ntoktreated, &ntoktransposed , &npbunches, &STEAM_DIRECTION))
    return NULL;

  Py_BEGIN_ALLOW_THREADS ;

  CCspace_tranpose_chunk   ( self->myCCspace ,sn, ntoktreated, ntoktransposed , npbunches, STEAM_DIRECTION );

  Py_END_ALLOW_THREADS  ;
  Py_INCREF( Py_None);
  return Py_None;
}
// C.tranpose_chunk(psn, ntoktreated, ntoktransposed, NPBUNCHES )
static PyObject *
Cspace_dispense_chunk( PyObject *self_a, PyObject *args)
{
  Cspace *self;
  int  sn, ntoktransposed , npbunches ;
  int STEAM_DIRECTION;

  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;
  if(!PyArg_ParseTuple(args,"iiii:Cspace_dispense_chunk", &sn , &ntoktransposed , &npbunches, &STEAM_DIRECTION))
    return NULL;
  Py_BEGIN_ALLOW_THREADS ;

  if(STEAM_DIRECTION==1) {
    CCspace_dispense_chunk   ( self->myCCspace ,sn,  ntoktransposed , npbunches  );
  }

  Py_END_ALLOW_THREADS  ;
  Py_INCREF( Py_None);
  return Py_None;
}


static PyObject *
Cspace_preprocess_chunk( PyObject *self_a, PyObject *args)
{
  Cspace *self;
  int  sn, ntok,ntokt,  npbunches, ncpus, do_ff2;
  int STEAM_DIRECTION;

  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;


  if(!PyArg_ParseTuple(args,"iiiiiii:Cspace_preprocess_chunk", &sn, &ntok, &ntokt, &npbunches, &ncpus, &STEAM_DIRECTION, &do_ff2))
    return NULL;

  /* sn  =cpyutils_o2i(Osn   ); */
  /* ntok=cpyutils_o2i(Ontok ); */

  Py_BEGIN_ALLOW_THREADS ;


  if(STEAM_DIRECTION==1) {
    CCspace_preprocess_chunk   ( self->myCCspace ,sn,  ntok ,  ntokt, npbunches, ncpus, do_ff2 );
  }

  Py_END_ALLOW_THREADS  ;

  Py_INCREF( Py_None);
  return Py_None;
}





static PyObject *
Cspace_InterleavedReadingPreProcessing_chunk ( PyObject *self_a, PyObject *args)
{
  Cspace *self;
  int  sn, ntok,ntokt,  npbunches, ncpus, do_ff2;
  int STEAM_DIRECTION;

  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;

  if(!PyArg_ParseTuple(args,"iiiiiii:Cspace_preprocess_chunk", &sn, &ntok, &ntokt, &npbunches, &ncpus, &STEAM_DIRECTION, &do_ff2))
    return NULL;

  /* sn  =cpyutils_o2i(Osn   ); */
  /* ntok=cpyutils_o2i(Ontok ); */

  Py_BEGIN_ALLOW_THREADS ;

  if(STEAM_DIRECTION==1) {
    CCspace_InterleavedReadingPreProcessing_chunk   ( self->myCCspace ,sn,  ntok ,  ntokt, npbunches, ncpus, do_ff2 );
  }

  Py_END_ALLOW_THREADS  ;

  Py_INCREF( Py_None);
  return Py_None;
}



static PyObject *
Cspace_getSaturations( PyObject *self_a, PyObject *args)
{
  Cspace *self;
  double aMin, aMax;
  double sat1, sat2;
  double Sat1, Sat2;

  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;


  if(!PyArg_ParseTuple(args,"dd:Cspace_getSaturations", &aMin,&aMax))
    return NULL;

  Py_BEGIN_ALLOW_THREADS ;

  CCspace_getSaturations( self->myCCspace, aMin,aMax, &sat1, &sat2, &Sat1, &Sat2 );
  Py_END_ALLOW_THREADS  ;

  return Py_BuildValue("OOOO", PyFloat_FromDouble(sat1), PyFloat_FromDouble(sat2)
		       , PyFloat_FromDouble(Sat1), PyFloat_FromDouble(Sat2));

}




static PyObject *
Cspace_reconstruct_chunk( PyObject *self_a, PyObject *args)
{
  Cspace *self;
  int  sn,  npbunches, ncpus;
  int STEAM_DIRECTION;

  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;


  if(!PyArg_ParseTuple(args,"iiii:Cspace_reconstruct_chunk", &sn, &npbunches, &ncpus, &STEAM_DIRECTION))
    return NULL;


  Py_BEGIN_ALLOW_THREADS ;

  CCspace_reconstruct   ( self->myCCspace ,sn,   npbunches, ncpus,  STEAM_DIRECTION );

  Py_END_ALLOW_THREADS  ;

  Py_INCREF( Py_None);
  return Py_None;
}

static PyObject *
Cspace_reconstructSHARED_chunk( PyObject *self_a, PyObject *args)
{
  Cspace *self;
  int  sn,  npbunches, ncpus, ntoktransposed;
  int STEAM_DIRECTION;

  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;


  if(!PyArg_ParseTuple(args,"iiiii:Cspace_reconstructSHARED_chunk", &sn, &npbunches, &ntoktransposed, &ncpus, &STEAM_DIRECTION))
    return NULL;

  Py_BEGIN_ALLOW_THREADS ;

  CCspace_reconstructSHARED   ( self->myCCspace ,sn,   npbunches, ntoktransposed,  ncpus ,  STEAM_DIRECTION);

  Py_END_ALLOW_THREADS  ;

  Py_INCREF( Py_None);
  return Py_None;
}

void       initialize_LT_sparse_infos(PyObject *   Oinfos, LT_infos* lt_infos     ) {
  lt_infos->C   = (float*)  cpyutils_PyArray1D_as_array(cpyutils_getattribute(Oinfos,"Csparse"), &(lt_infos->N), NPY_FLOAT32 );    ; 
  lt_infos->II  = (int*)   cpyutils_PyArray1D_as_array(cpyutils_getattribute(Oinfos,"Isparse"), &(lt_infos->N), NPY_INT32 );    ; 
  lt_infos->JJ  =  (int*)    cpyutils_PyArray1D_as_array(cpyutils_getattribute(Oinfos,"Jsparse"), &(lt_infos->N), NPY_INT32 );    ; 
  
  lt_infos->sigmas  = (float*)  cpyutils_PyArray1D_as_array(cpyutils_getattribute(Oinfos,"Sigmas"), &(lt_infos->Nsigmas), NPY_FLOAT32 );    ; 
  
  lt_infos->SLD  = cpyutils_o2i(cpyutils_getattribute(Oinfos ,"SINO_leading_dimension")); 
  
  lt_infos->C2s  =  (float*) cpyutils_PyArray1D_as_array(cpyutils_getattribute(Oinfos,"Csparse_2slice"), &(lt_infos->N2s), NPY_FLOAT32 );    ; 
  lt_infos->I2s  =  (int*)  cpyutils_PyArray1D_as_array(cpyutils_getattribute(Oinfos,"Isparse_2slice"), &(lt_infos->N2s), NPY_INT32 );    ; 
  lt_infos->J2s  = (int*)  cpyutils_PyArray1D_as_array(cpyutils_getattribute(Oinfos,"Jsparse_2slice"), &(lt_infos->N2s), NPY_INT32 );

  int i;

  lt_infos->Ng2s = 0;
  for(i=0; i< lt_infos->N2s; i++) {
    lt_infos->Ng2s  = max( lt_infos->Ng2s, lt_infos->J2s[i]+1   ) ;
  }

  lt_infos->Ng = 0;
  lt_infos->force_per_gaussian = 0.0;
  double de;
  for(i=0; i< lt_infos->N; i++) {
    
    float sigma = lt_infos->sigmas[lt_infos->II[i] / lt_infos->SLD ];
    
    lt_infos->Ng  = max( lt_infos->Ng, lt_infos->JJ[i]+1  ) ;
    de =  lt_infos->C[i]  *  M_PI/(2*  lt_infos->nprojs)  ; 
    if(lt_infos->JJ[i]<lt_infos->Ng2s)  lt_infos->force_per_gaussian += de*de / sigma;  // stima approssimata
  }
  lt_infos->force_per_gaussian /= lt_infos->Ng2s ;

  lt_infos->Nslice = 0;
  printf(" CERCO IL MASSIMO DI I2S su %d \n", lt_infos->N2s );// debug// debug
  for(i=0; i< lt_infos->N2s; i++) {
    lt_infos->Nslice  = max( lt_infos->Nslice, lt_infos->I2s[i] +1  ) ;
  }
  printf(" IL MASSIMO DI I2S %d \n", lt_infos->Nslice );// debug

}

#if PY_MAJOR_VERSION >= 3
static PyObject *
Cspace_new( PyObject *self, PyObject *args, PyObject *kwds)
#else
static PyObject *
Cspace_new( PyObject *self, PyObject *args)
  
#endif
  
{

  printf(" entered in Cspace_new \n");
  PyObject *Oarrayspace ;
  PyObject *Otmp;
  PyArrayObject *Oa;
  int i,k, dumint;

  Cspace* res;
  char * CCD_FILTER_ptr;
  char * RING_FILTER_ptr;
  
  res= (Cspace*) PyObject_NEW(Cspace , &Cspacetype);
  res->myCCspace =  (CCspace*) malloc(sizeof( CCspace));
  res->myCCspace->ff2_status = -1;
  res->myCCspace->ff2_localmean_threads = NULL;
  CCspace_initialise( res->myCCspace );

  if(!PyArg_ParseTuple(args,"OOs:Cspace_new",&Oarrayspace,&(res->OParameters),
		       &(res->myCCspace->params.nome_directory_distribution)
		       ))
    return NULL;

  Py_INCREF(res->OParameters);

  PyObject ** Optrs[] = {&(res->Orawdataarray),  &(res->Off_rawdataarray),  &(res->Odataarray), &(res->Otransposeddataarray) };
  const char  *keys[] = {  "rawdatatokens",  "ff_rawdatatokens", "datatokens" ,"transposeddatatokens" };
  for(k=0;k<4;k++) {
    Otmp = *(Optrs[k])  = cpyutils_get_pydic_Oval(Oarrayspace ,keys[k]  )  ;
    Py_INCREF(*Optrs[k]);
    assert( PyList_Check( Otmp )  );
    for(i=0;i<PyList_Size(Otmp);i++)  {
      assert(PyArray_Check( PyList_GetItem( Otmp , i)));
      Oa = ((PyArrayObject*) PyList_GetItem( Otmp , i));
      assert(PyArray_ISFLOAT(Oa));
      CCspace_add2DataSpace( res->myCCspace , ((float *) PyArray_DATA(Oa) ), keys[k]  );
    }
  }

  Otmp =  cpyutils_get_pydic_Oval(Oarrayspace ,  "patches" )  ;
  Py_INCREF(Otmp);
  {
    int dima, dimb ;
    res->myCCspace->params.patches  = (float *) cpyutils_PyArray5D_as_array(Otmp,&(res->myCCspace->params.patches_N),
								  &(res->myCCspace->params.patches_vecto),
								  &(res->myCCspace->params.patches_epaisseur),
								  &(dima),
								  &(dimb),
								  NPY_FLOAT32  );
    assert(dima==dimb);
    res->myCCspace->params.patches_dim=dima;
    res->myCCspace->params.patches_size =   dima*dimb *res->myCCspace->params.patches_epaisseur*res->myCCspace->params.patches_vecto  ;
  }

  res->Oaxis_corrections =   cpyutils_getattribute(res->OParameters ,"axis_corrections" )  ;
  //cpyutils_get_pydic_Oval(Oarrayspace , "axis_corrections"  )    ;
  Py_INCREF(res->Oaxis_corrections);
  res->myCCspace->axis_corrections =  ((float *) PyArray_DATA ((PyArrayObject *)res->Oaxis_corrections) ) ;


  res->Oaxis_correctionsL =  cpyutils_getattribute(res->OParameters ,"axis_correctionsL" )  ;
  // cpyutils_get_pydic_Oval(Oarrayspace , "axis_correctionsL"  )    ;

  Py_INCREF(res->Oaxis_correctionsL);
  res->myCCspace->axis_correctionsL =  ((float *)  PyArray_DATA((PyArrayObject *)res->Oaxis_correctionsL) ) ;



  int do_bh_lut;
  do_bh_lut = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"DO_BH_LUT" )  );
  if(do_bh_lut==0) {
    res->myCCspace->params.BH_LUT_U = NULL ;
    res->myCCspace->params.BH_LUT_F = NULL ;
  } else {
    res->myCCspace->params.BH_LUT_U  =  (float *) cpyutils_PyArray1D_as_array(cpyutils_get_pydic_Oval(Otmp,"BH_LUT_U"),&(res->myCCspace->params.BH_LUT_N), NPY_FLOAT32  );
    res->myCCspace->params.BH_LUT_F  = (float*)  cpyutils_PyArray1D_as_array(cpyutils_get_pydic_Oval(Otmp,"BH_LUT_F"),&(res->myCCspace->params.BH_LUT_N), NPY_FLOAT32  );    
  }

  res->myCCspace->reading_infos.CURRENT_NAME =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"CURRENT_NAME" ) );
  
  int do_distortion ;
  do_distortion = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"DO_DISTORTION" )  );
  if(do_distortion==0) {
    res->myCCspace->params.dist_h = NULL ;
    res->myCCspace->params.dist_v = NULL ;
  } else {
    int nrow, ncol;

    res->myCCspace->params.dist_h = (float *)  cpyutils_PyArray2D_as_array(cpyutils_getattribute(res->OParameters,"DIST_H"),&(res->myCCspace->params.dist_nrow),&(res->myCCspace->params.dist_ncol), NPY_FLOAT32  );
    res->myCCspace->params.dist_v = (float *)  cpyutils_PyArray2D_as_array(cpyutils_getattribute(res->OParameters,"DIST_V"),&(nrow),&(ncol), NPY_FLOAT32  );

    if (  res->myCCspace->params.dist_nrow != nrow  || res->myCCspace->params.dist_ncol   != ncol  )  {
      fprintf(stderr,"ERROR:  DIST_H and DIST_V must have the same dimensions\n");
      assert(   res->myCCspace->params.dist_nrow = nrow     );
      assert(   res->myCCspace->params.dist_ncol = ncol     );
    }
  }
  res->Offcorr = cpyutils_get_pydic_Oval(Oarrayspace , "doubleffcorrection"  )    ;
  Py_INCREF(res->Offcorr);
  res->myCCspace->ffcorr =  (float *)  PyArray_DATA((PyArrayObject *)res->Offcorr) ;

  res->myCCspace->params.REFERENCES_HOTPIXEL_THRESHOLD = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"REFERENCES_HOTPIXEL_THRESHOLD" )  );
  
  res->Obackground = cpyutils_get_pydic_Oval(Oarrayspace , "background"  )    ;
  {
    assert(PyArray_Check( res->Obackground  ));
    Py_INCREF(res->Obackground);
    assert( PyArray_NDIM((PyArrayObject*) res->Obackground )  == 2   || PyArray_NDIM((PyArrayObject*) res->Obackground )  == 3    );
    
    int dim2,dim1;
    
    if( PyArray_NDIM((PyArrayObject*) res->Obackground ) ==3 ){
      printf(" PyArray_NDIM((PyArrayObject*) res->Obackground ) ==3\n");
      int dimx;
      res->myCCspace->background    = (float*) cpyutils_PyArray3D_as_array(  res->Obackground   , &dim2, &dim1, &dimx , NPY_FLOAT32 );
      printf(" median  npbunches \n" );
      int npbunches =      cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"NPBUNCHES" )  );   ; 
      res->myCCspace->background    = medianX(  res->myCCspace->background    , dim2, dim1, dimx ,   npbunches );
      printf(" median applied \n");
      
    } else {
      
      res->myCCspace->background    = (float*) cpyutils_PyArray2D_as_array(  res->Obackground   , &dim2, &dim1, NPY_FLOAT32 );
      
    }
    if ( res->myCCspace->params.REFERENCES_HOTPIXEL_THRESHOLD ) {
      
      float * new_back = (float*) malloc(      dim2*dim1*  sizeof(float) ) ;
      
      CCD_Filter_Implementation( new_back, res->myCCspace->background, dim2 , dim1 ,res->myCCspace->params.REFERENCES_HOTPIXEL_THRESHOLD , 1);
      
      res->myCCspace->background   = new_back ;
      
    }
    
  }

  
  if(!PyArray_Check(cpyutils_getattribute(res->OParameters ,"angles" ))) {
    res->myCCspace->params.do_custom_angles=0;
  } else {
    res->Oangles =   cpyutils_getattribute(res->OParameters ,"angles" )  ;
    Py_INCREF(res->Oangles);
    res->myCCspace->params.custom_angles =  ((float *)  PyArray_DATA((PyArrayObject *)res->Oangles) ) ;
    res->myCCspace->params.do_custom_angles=1;
  }

  if(!PyArray_Check(cpyutils_getattribute(res->OParameters ,"ignore" ))) {
    res->myCCspace->params.do_ignore_projections=0;
  } else {
    res->Iangles =   cpyutils_getattribute(res->OParameters ,"ignore" )  ;
    Py_INCREF(res->Iangles);
    res->myCCspace->params.ignore_angles =  ((int *)  PyArray_DATA((PyArrayObject *)res->Iangles) ) ;
    res->myCCspace->params.do_ignore_projections= cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"n_ignore" )  ); ;
  }


  MPI_Comm_rank(MPI_COMM_WORLD,&(res->iproc));
  MPI_Comm_size(MPI_COMM_WORLD,&(res->nprocs));
  cspace_iproc= res->iproc;

  res->myCCspace->params.SUBTRACT_BACKGROUND = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"SUBTRACT_BACKGROUND" )  );


  res->myCCspace->params.CORRECT_FLATFIELD = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"CORRECT_FLATFIELD" )  );

  res->myCCspace->params.OFFSETRADIOETFF = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"OFFSETRADIOETFF" )  );
  res->myCCspace->params.TAKE_LOGARITHM = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"TAKE_LOGARITHM" )  );
  res->myCCspace->params.ZEROCLIPVALUE = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"ZEROCLIPVALUE" )  );
  res->myCCspace->params.ONECLIPVALUE = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"ONECLIPVALUE" )  );

  res->myCCspace->params.NUM_IMAGE_1 = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"NUM_IMAGE_1" )  );
  res->myCCspace->params.NUM_IMAGE_2 = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"NUM_IMAGE_2" )  );

  res->myCCspace->params.DO_PAGANIN  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DO_PAGANIN" ) );
  res->myCCspace->params.PAGANIN_Lmicron  = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"PAGANIN_Lmicron" ) );
  res->myCCspace->params.PAGANIN_MARGE  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"PAGANIN_MARGE" ) );
  res->myCCspace->params.IMAGE_PIXEL_SIZE_2  = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"IMAGE_PIXEL_SIZE_2" ) );
  res->myCCspace->params.IMAGE_PIXEL_SIZE_1  = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"IMAGE_PIXEL_SIZE_1" ) );
  // res->myCCspace->params.VOXEL_SIZE          = res->myCCspace->params.IMAGE_PIXEL_SIZE_1  ;
  res->myCCspace->params.VOXEL_SIZE          =  cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"VOXEL_SIZE" ) );
  res->myCCspace->params.PUS  = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"PUS" ) );
  res->myCCspace->params.PUC  = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"PUC" ) );
  res->myCCspace->params.UNSHARP_LoG  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"UNSHARP_LOG" ) );

  res->myCCspace->params.NEURAL_TRAINING_PIXELS_PER_IMAGE  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"NNFBP_TRAINING_PIXELS_PER_SLICE" ) );
  res->myCCspace->params.NEURAL_TRAINING_NLINEAR  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"NNFBP_NLINEAR" ) );
  res->myCCspace->params.NEURAL_TRAINING_RECONSTRUCTION_FILE =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"NNFBP_TRAINING_RECONSTRUCTION_FILE" ) );
  res->myCCspace->params.NEURAL_TRAINING_USEMASK  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"NNFBP_TRAINING_USEMASK" ) );
  res->myCCspace->params.NEURAL_TRAINING_MASK_FILE =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"NNFBP_TRAINING_MASK_FILE" ) );


  res->myCCspace->params.DO_OUTPUT_PAGANIN  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DO_OUTPUT_PAGANIN" ) );
  if( res->myCCspace->params.DO_OUTPUT_PAGANIN)
    res->myCCspace->params.OUTPUT_PAGANIN_FILE = cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"OUTPUT_PAGANIN_FILE") );

  res->myCCspace->params.ROTATION_AXIS_POSITION  = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"ROTATION_AXIS_POSITION" ) );

  res->myCCspace->params.OUTPUT_FILE =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"OUTPUT_FILE" ) );
  res->myCCspace->params.PROJ_OUTPUT_FILE  =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"PROJ_OUTPUT_FILE" ) );

  res->myCCspace->params.OUTPUT_FILE_ORIG =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"OUTPUT_FILE_ORIG" ) );
  res->myCCspace->params.OUTPUT_FILE_HISTOGRAM =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"OUTPUT_FILE_HISTOGRAM" ) );
  /*   res->myCCspace->params.INFOOUTPUT  =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"INFOOUTPUT" ) );  */
  /*   res->myCCspace->params.XMLOUTPUT   =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"XMLOUTPUT" ) );  */

  res->myCCspace->params.SUMRULE  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"SUMRULE" ) );
  res->myCCspace->params.FBFILTER  = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"FBFILTER" ) );
  {
    int tmpInt;
    res->myCCspace->params.FBFACTORS = (float*) cpyutils_PyArray1D_as_array(cpyutils_getattribute(res->OParameters,"FBFACTORS"),&tmpInt,NPY_FLOAT32);
  }
  {
    res->myCCspace->params.intervals_hrings = (int*) cpyutils_PyArray1D_as_array(cpyutils_getattribute(res->OParameters,"INTERVALS_HRINGS"),
									  &(res->myCCspace->params.N_intervals_hrings),NPY_INT32);
  }



  if(res->myCCspace->params.FBFILTER==10) {
    res->myCCspace->params.DFI_NOFVALUES    = cpyutils_o2i ( cpyutils_getattribute(res->OParameters ,"DFI_NOFVALUES" )  ) ;
    res->myCCspace->params.DFI_KERNEL_SIZE  = cpyutils_o2i ( cpyutils_getattribute(res->OParameters ,"DFI_KERNEL_SIZE" )  ) ;
    res->myCCspace->params.DFI_OVERSAMPLING_RATE  = cpyutils_o2i ( cpyutils_getattribute(res->OParameters ,"DFI_OVERSAMPLING_RATE" )  ) ;
    res->myCCspace->params.DFI_R2C_MODE  = cpyutils_o2i ( cpyutils_getattribute(res->OParameters ,"DFI_R2C_MODE" )  ) ;
  }



  res->myCCspace->params.JOSEPHNOCLIP  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"JOSEPHNOCLIP" ) );

  res->myCCspace->params.DETECTOR_DUTY_RATIO         = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"DETECTOR_DUTY_RATIO" ) );

  res->myCCspace->params.DETECTOR_DUTY_OVERSAMPLING  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DETECTOR_DUTY_OVERSAMPLING" ) );

  res->myCCspace->params.ROTATION_VERTICAL  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"ROTATION_VERTICAL" ) );

  res->myCCspace->params.start_x  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"START_VOXEL_1" ) ) -1;
  res->myCCspace->params.start_y  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"START_VOXEL_2" ) ) -1;
  res->myCCspace->params.num_x    = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"END_VOXEL_1" ) )-res->myCCspace->params.start_x ;
  res->myCCspace->params.num_y    = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"END_VOXEL_2" ) )-res->myCCspace->params.start_y;
  res->myCCspace->params.ITERATIVE_CORRECTIONS   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"ITERATIVE_CORRECTIONS" ) );
  res->myCCspace->params.PENALTY_TYPE            = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"PENALTY_TYPE" ) );
  res->myCCspace->params.OPTIM_ALGORITHM         = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"OPTIM_ALGORITHM" ) );
  res->myCCspace->params.SMOOTH_PENALTY_PARAM    = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"SMOOTH_PENALTY_PARAM" ) );
  res->myCCspace->params.LINE_SEARCH_INIT        = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"LINE_SEARCH_INIT" ) );
  res->myCCspace->params.VECTORIALITY            = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"VECTORIALITY" ) );
  res->myCCspace->params.peso_overlap            = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"WEIGHT_OVERLAP" ) );
  //  res->myCCspace->params.ITERATIVE_CORRECTIONS   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"ITERATIVE_CORRECTIONS" ) ); //TODO : PRECOND


  res->myCCspace->params.CONICITY   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"CONICITY" ) );
  res->myCCspace->params.CONICITY_FAN   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"CONICITY_FAN" ) );
  res->myCCspace->params.SOURCE_DISTANCE   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"SOURCE_DISTANCE" ) );
  res->myCCspace->params.DETECTOR_DISTANCE   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"DETECTOR_DISTANCE" ) );
  res->myCCspace->params.SOURCE_X   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"SOURCE_X" ) );
  res->myCCspace->params.SOURCE_Y   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"SOURCE_Y" ) );
  
  res->myCCspace->params.DECT_PSI    = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"DECT_PSI"  ) );
  res->myCCspace->params.DECT_TILT   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"DECT_TILT" ) );

  res->myCCspace->params.DZPERPROJ   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"DZPERPROJ" ) );
  res->myCCspace->params.DXPERPROJ   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"DXPERPROJ" ) );



  Otmp =  cpyutils_getattribute(res->OParameters ,"CONICITY_MARGIN_UP" );
  res->myCCspace->params.CONICITY_MARGIN_UP =(int*) cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );
  Otmp =  cpyutils_getattribute(res->OParameters ,"CONICITY_MARGIN_DOWN" );
  res->myCCspace->params.CONICITY_MARGIN_DOWN =(int*)cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );

  Otmp =  cpyutils_getattribute(res->OParameters ,"CONICITY_MARGIN_UP_wished" );
  res->myCCspace->params.CONICITY_MARGIN_UP_wished =(int*)cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );
  Otmp =  cpyutils_getattribute(res->OParameters ,"CONICITY_MARGIN_DOWN_wished" );
  res->myCCspace->params.CONICITY_MARGIN_DOWN_wished =(int*)cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );


  Otmp =  cpyutils_getattribute(res->OParameters ,"first_slices_2r" );
  res->myCCspace->params.first_slices_2r =(int*) cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );

  Otmp =  cpyutils_getattribute(res->OParameters ,"last_slices_2r" );
  res->myCCspace->params.last_slices_2r =(int*) cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );

  res->myCCspace->params.patch_ep =cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"patch_ep" ) );



  Otmp =  cpyutils_getattribute(res->OParameters ,"first_slices" );
  res->myCCspace->params.first_slices =(int*) cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );

  Otmp =  cpyutils_getattribute(res->OParameters ,"last_slices" );
  res->myCCspace->params.last_slices =(int*) cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );

  Otmp =  cpyutils_getattribute(res->OParameters ,"corr_slice_slicedect" );
  res->myCCspace->params.corr_slice_slicedect =(int*) cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_INT32 );

  res->myCCspace->params.CONICITY_MARGIN =cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"CONICITY_MARGIN" ) );



  if( res->myCCspace->params.ITERATIVE_CORRECTIONS )  {
    printf(" res->myCCspace->params.VECTORIALITY  %d \n", res->myCCspace->params.VECTORIALITY );
    printf("  res->myCCspace->params.patches_vecto %d \n", res->myCCspace->params.patches_vecto );
    assert(res->myCCspace->params.VECTORIALITY==res->myCCspace->params.patches_vecto) ;
  }

  res->myCCspace->params.FISTA =  cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"FISTA" ) );
  res->myCCspace->params.DENOISING_TYPE   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DENOISING_TYPE" ) );
  res->myCCspace->params.CALM_ZONE_LEN   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"CALM_ZONE_LEN" ) );
  res->myCCspace->params.NLM_NOISE_GEOMETRIC_RATIO   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"NLM_NOISE_GEOMETRIC_RATIO" ) );
  res->myCCspace->params.NLM_NOISE_INITIAL_FACTOR   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"NLM_NOISE_INITIAL_FACTOR" ) );

  res->myCCspace->params.DO_PRECONDITION   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DO_PRECONDITION" ) );
  res->myCCspace->params.BETA_TV   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"BETA_TV" ) );
  res->myCCspace->params.N_ITERS_DENOISING   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"N_ITERS_DENOISING" ) );
  res->myCCspace->params.DUAL_GAP_STOP   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"DUAL_GAP_STOP" ) );
  res->myCCspace->params.STEPFORPATCHES   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"STEPFORPATCHES" ) );

  res->myCCspace->params.ITER_RING_HEIGHT   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"ITER_RING_HEIGHT" ) );

  res->myCCspace->params.ITER_RING_SIZE   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"ITER_RING_SIZE" ) );
  res->myCCspace->params.ITER_RING_BETA   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"ITER_RING_BETA" ) );
  res->myCCspace->params.NUMBER_OF_RINGS   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"NUMBER_OF_RINGS" ) );
  res->myCCspace->params.LIPSCHITZFACTOR   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"LIPSCHITZFACTOR" ) );
  res->myCCspace->params.LIPSCHITZ_ITERATIONS   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"LIPSCHITZ_ITERATIONS" ) ); //PP.add
  res->myCCspace->params.RING_ALPHA   = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"RING_ALPHA" ) ); //PP.add
  res->myCCspace->params.do_dump_hrings   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DO_DUMP_HRINGS" ) ); //PP.add
  // For DFI and DFP
  res->myCCspace->params.USE_DFI = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"USE_DFI"));
  res->myCCspace->params.USE_DFP = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"USE_DFP"));
  // For wavelets
  res->myCCspace->params.W_LEVELS = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"W_LEVELS"));
  res->myCCspace->params.W_CYCLE_SPIN = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"W_CYCLE_SPIN"));
  res->myCCspace->params.W_FISTA_PARAM = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"W_FISTA_PARAM"));
  res->myCCspace->params.W_SWT = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"W_SWT"));
  res->myCCspace->params.W_NORMALIZE = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"W_NORMALIZE"));
  res->myCCspace->params.W_WNAME = cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"W_WNAME"));
  res->myCCspace->params.W_THRESHOLD_APPCOEFFS = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"W_THRESHOLD_APPCOEFFS"));
  res->myCCspace->params.W_THRESHOLD_COUSINS = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"W_THRESHOLD_COUSINS"));
  // Munch filter
  res->myCCspace->params.FW_LEVELS = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"FW_LEVELS"));
  res->myCCspace->params.FW_SIGMA = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"FW_SIGMA"));
  res->myCCspace->params.FW_WNAME = cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"FW_WNAME"));
  res->myCCspace->params.FW_SCALING = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"FW_SCALING"));
  res->myCCspace->params.FW_FILTERPARAM = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"FW_FILTERPARAM"));
  // Projections averaging
  res->myCCspace->params.FF2_SIGMA = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"FF2_SIGMA"));


  // Fluo
  res->myCCspace->params.FLUO_SINO = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"FLUO_SINO"));
  res->myCCspace->params.FLUO_ITERS = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"FLUO_ITERS"));

  // For SIRT-Filter
  res->myCCspace->params.SF_ITERATIONS = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"SF_ITERATIONS"));
  res->myCCspace->params.SF_FILTER     = (float*) cpyutils_PyArray1D_as_array(cpyutils_getattribute(res->OParameters,"SF_FILTER"), &dumint, NPY_FLOAT32 );
  res->myCCspace->params.SF_SAVEDIR = cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"SF_FILTER_FILE"));
  res->myCCspace->params.SF_LAMBDA = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"SF_LAMBDA"));

  //
  res->myCCspace->params.DATA_IS_FILTERED = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"DATA_IS_FILTERED"));
  res->myCCspace->params.ESTIMATE_BETA = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"ESTIMATE_BETA"));

  // TV+L2
  res->myCCspace->params.BETA_L2 = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"BETA_L2"));

  // Positivity constraint
  res->myCCspace->params.ITER_POS_CONSTRAINT = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"ITER_POS_CONSTRAINT"));

  res->myCCspace->params.STRAIGTHEN_SINOS   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"STRAIGTHEN_SINOS" ) );
  res->myCCspace->params.OUTPUT_SINOGRAMS   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"OUTPUT_SINOGRAMS" ) );
  res->myCCspace->params.FILE_INTERVAL  =   cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"FILE_INTERVAL" ) );
  res->myCCspace->params.NUM_FIRST_IMAGE  =   cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"NUM_FIRST_IMAGE" ) );

  res->myCCspace->reading_infos.NUM_FIRST_IMAGE = res->myCCspace->params.NUM_FIRST_IMAGE;


  res->myCCspace->reading_infos.numpjs =   cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"numpjs")) ;
  res->myCCspace->reading_infos.numpjs_span =  cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"numpjs_span"));
  res->myCCspace->reading_infos.NUM_LAST_IMAGE =   cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"NUM_LAST_IMAGE")) ;


  res->myCCspace->reading_infos.Dim_1 = 0;
  res->myCCspace->reading_infos.Dim_2 = 0;
  res->myCCspace->reading_infos.datatype =  0; 

  

  if(res->myCCspace->params.do_custom_angles==1) {
    assert( PyArray_DIMS((PyArrayObject *)res->Oangles)[0] == res->myCCspace->reading_infos.numpjs );
  }
  assert( PyArray_DIMS((PyArrayObject *)res->Oaxis_corrections)[0] == res->myCCspace->reading_infos.numpjs );
  assert( PyArray_DIMS((PyArrayObject *)res->Oaxis_correctionsL)[0] == res->myCCspace->reading_infos.numpjs );

  res->myCCspace->params.EDFOUTPUT = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"EDFOUTPUT" ) );


  res->myCCspace->params.ANGLE_BETWEEN_PROJECTIONS = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"ANGLE_BETWEEN_PROJECTIONS" ) );
  res->myCCspace->params.ANGLE_OFFSET = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"ANGLE_OFFSET" ) );
  res->myCCspace->params.OVERSAMPLING_FACTOR   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"OVERSAMPLING_FACTOR" ) );
  res->myCCspace->params.AXIS_TO_THE_CENTER  =cpyutils_o2i(cpyutils_getattribute(res->OParameters,"AXIS_TO_THE_CENTER")) ;
  res->myCCspace->params.AVOIDHALFTOMO  =cpyutils_o2i(cpyutils_getattribute(res->OParameters,"AVOIDHALFTOMO")) ;

  res->myCCspace->params.PADDING =  cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"PADDING" ) );
  res->myCCspace->params.PENTEZONE = cpyutils_o2f (cpyutils_getattribute(res->OParameters ,"PENTEZONE" ) );

  res->myCCspace->params.zerooffmask = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"ZEROOFFMASK" ) );
  res->myCCspace->params.SUMRULE = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"SUMRULE" ) );
  res->myCCspace->params.TRYGPU = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"TRYGPU" ) );
  res->myCCspace->params.TRYGPUCCDFILTER = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"TRYGPUCCDFILTER" ) );

  res->myCCspace->params.ALLOWBOTHGPUCPU = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"ALLOWBOTHGPUCPU" ) );
  res->myCCspace->params.RAWDATA_MEMORY_REUSE = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"RAWDATA_MEMORY_REUSE" ) );
  res->myCCspace->params.BINNING = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"BINNING" ) );

  res->myCCspace->params.MULTIFRAME = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"MULTIFRAME" ) );
  res->myCCspace->reading_infos.MULTIFRAME = res->myCCspace->params.MULTIFRAME;

  res->myCCspace->params.MYGPU = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"MYGPU" ) );

  res->myCCspace->params.STEAM_INVERTER = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"STEAM_INVERTER" ) );
  res->myCCspace->params.PROJ_OUTPUT_RESTRAINED = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"PROJ_OUTPUT_RESTRAINED" ) );


  res->myCCspace->params.verbosity   = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"VERBOSITY" ) );


  if(  cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DO_CCD_FILTER"))==0 ) {
    res->myCCspace->params.CCD_FILTER_KIND  =CCD_FILTER_NONE_ID ;
  } else {
    CCD_FILTER_ptr = cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"CCD_FILTER" ) );
    if(strcmp(CCD_FILTER_ptr,"CCD_Filter")==0) {
      void * voidptr;
      res->myCCspace->params.CCD_FILTER_KIND  = CCD_Filter_ID;
      res->myCCspace->params.CCD_FILTER_PARA = (void*) malloc( sizeof(CCD_Filter_PARA_struct) );
      Otmp = cpyutils_getattribute(res->OParameters ,"CCD_FILTER_PARA" );
      voidptr = res->myCCspace->params.CCD_FILTER_PARA ;
      ((CCD_Filter_PARA_struct*) voidptr)->threshold =cpyutils_o2f (cpyutils_get_pydic_Oval(Otmp,"threshold" ) )  ;
    } else {
      printf("DO_CCD_FILTER is ON but option %s for CCD_FILTER parameter  yet unknown \n",CCD_FILTER_ptr );
      exit(1);
    }
  }

  if( cpyutils_o2i(cpyutils_getattribute(res->OParameters,"ITERATIVE_CORRECTIONS"))>0 && cpyutils_o2i(cpyutils_getattribute(res->OParameters,"DENOISING_TYPE"))==5){
    Otmp = cpyutils_getattribute(res->OParameters,"neural_params");
    int tmpInt;
    res->myCCspace->params.NEURAL_FILTERS = (float*) cpyutils_PyArray2D_as_array(cpyutils_get_pydic_Oval(Otmp,"filters"),&(res->myCCspace->params.NEURAL_NFILTERS),&(res->myCCspace->params.NEURAL_FILTERSIZE), NPY_FLOAT32  );
    res->myCCspace->params.NEURAL_OFFSETS =(float*) cpyutils_PyArray1D_as_array(cpyutils_get_pydic_Oval(Otmp,"offsets"),&tmpInt,NPY_FLOAT32);
    res->myCCspace->params.NEURAL_WEIGHTS = (float*) cpyutils_PyArray1D_as_array(cpyutils_get_pydic_Oval(Otmp,"weights"),&tmpInt,NPY_FLOAT32);
    res->myCCspace->params.NEURAL_MININ = cpyutils_o2f(cpyutils_get_pydic_Oval(Otmp,"minIn"));
    res->myCCspace->params.NEURAL_MAXIN = cpyutils_o2f(cpyutils_get_pydic_Oval(Otmp,"maxIn"));
  }

  printf(" controllo DO_RING_FILTER = %d \n",cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DO_RING_FILTER"))  );
  if(  (  res->myCCspace->params.DO_RING_FILTER  = cpyutils_o2i (cpyutils_getattribute(res->OParameters ,"DO_RING_FILTER")))==0 ) {
    res->myCCspace->params.RING_FILTER_KIND  =RING_FILTER_NONE_ID ;
  } else {
    RING_FILTER_ptr = cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"RING_FILTER" ) );

    if(strcmp(RING_FILTER_ptr,"RING_Filter")==0  ||  strcmp(RING_FILTER_ptr,"RING_Filter_THRESHOLDED")==0) {
      void * voidptr ;
      res->myCCspace->params.RING_FILTER_PARA = (void*) malloc( sizeof(RING_Filter_PARA_struct) );
      voidptr = res->myCCspace->params.RING_FILTER_PARA ;

      Otmp = cpyutils_getattribute(res->OParameters ,"RING_FILTER_PARA" );

      voidptr = res->myCCspace->params.RING_FILTER_PARA ;

      if(strcmp(RING_FILTER_ptr,"RING_Filter")==0  ) {
	res->myCCspace->params.RING_FILTER_KIND  = RING_Filter_ID;
      } else {

	res->myCCspace->params.RING_FILTER_KIND  = RING_Filter_THRESHOLDED_ID;
	((RING_Filter_PARA_struct*) voidptr)->threshold   = cpyutils_o2f (cpyutils_get_pydic_Oval(Otmp,"threshold" )  );

      }

      Otmp = cpyutils_get_pydic_Oval(Otmp,"FILTER" )   ;
      ((RING_Filter_PARA_struct*) voidptr)->FILTER   = (float*) cpyutils_PyArray1D_as_array(Otmp, &dumint, NPY_FLOAT32 );
      assert(dumint>= res->myCCspace->params.NUM_IMAGE_1 );

    } else   if(strcmp(RING_FILTER_ptr,"RING_Filter_SG")==0) {
      void * voidptr ;
      res->myCCspace->params.RING_FILTER_KIND  = RING_Filter_SG_ID;
      res->myCCspace->params.RING_FILTER_PARA = (void*) malloc( sizeof(RING_Filter_SG_PARA_struct) );
      Otmp = cpyutils_getattribute(res->OParameters ,"RING_FILTER_PARA" );
      voidptr = res->myCCspace->params.RING_FILTER_PARA ;

      ((RING_Filter_SG_PARA_struct*) voidptr)->LF       = cpyutils_o2i (cpyutils_getattribute(Otmp,"LF" ) )  ;
      ((RING_Filter_SG_PARA_struct*) voidptr)->I_Slope  = cpyutils_o2i (cpyutils_getattribute(Otmp,"I_Slope" ) )  ;
      ((RING_Filter_SG_PARA_struct*) voidptr)->Lfen     = cpyutils_o2i (cpyutils_getattribute(Otmp,"Lfen" ) )  ;
      ((RING_Filter_SG_PARA_struct*) voidptr)->Eps1     = cpyutils_o2f (cpyutils_getattribute(Otmp,"Eps1" ) )  ;
      ((RING_Filter_SG_PARA_struct*) voidptr)->Eps2     = cpyutils_o2f (cpyutils_getattribute(Otmp,"Eps2" ) )  ;
      ((RING_Filter_SG_PARA_struct*) voidptr)->RProt    = cpyutils_o2f (cpyutils_getattribute(Otmp,"RProt" ) )  ;

    } else {
      printf("DO_RING_FILTER is ON but option %s for RING_FILTER parameter  yet unknown \n",RING_FILTER_ptr );
      exit(1);
    }
  }

  printf(" OK 2\n" );
  if (cpyutils_getattribute(res->OParameters ,"ONECLIPVALUE" ) != Py_None ) {
    res->myCCspace->params.ONECLIPVALUE = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"ONECLIPVALUE" )  );
  } else {
    res->myCCspace->params.ONECLIPVALUE= -1.0 ;
  }
  {
    Otmp = cpyutils_getattribute(res->OParameters ,"DOUBLEFFCORRECTION" );
    if(PyInt_Check(Otmp)) {
      int ival ;
      ival = cpyutils_o2i( Otmp );
      if(ival) {
	printf("input error : DOUBLEFFCORRECTION must be zero ( no double ff ) or a string(filename) \n" );
	exit(1);
      }
      res->myCCspace->params.DOUBLEFFCORRECTION = NULL ;
    } else if (PyStr_Check(Otmp))  {
      res->myCCspace->params.DOUBLEFFCORRECTION = (char*) PyStr_AsString(Otmp);
    } else {
      printf("input error : DOUBLEFFCORRECTION must be zero ( no double ff ) or a string(filename) \n" );
      exit(1);
    }
  }


  // LT
  {
    int ltmargin = cpyutils_o2f(cpyutils_getattribute(res->OParameters ,"LT_MARGIN")); 
    if ( ltmargin == 0 ) {
      res->myCCspace->params.LT_pars = NULL;
    } else {
      
      res->myCCspace->params.LT_pars = (LT_Parameters*)malloc(sizeof(  LT_Parameters ));
      res->myCCspace->params.LT_pars->LT_MARGIN = ltmargin ;
      
      LT_Parameters* LT_pars =   res->myCCspace->params.LT_pars;
      LT_pars->LT_KNOWN_REGIONS_FILE = cpyutils_getstring(cpyutils_getattribute(res->OParameters ,"LT_KNOWN_REGIONS_FILE")); 
      LT_pars->LT_REBINNING = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"LT_REBINNING" ) );
      
      /*    */
      {
	printf("inizializzo coarse \n");
        LT_pars->lt_infos_coarse = (LT_infos*)malloc(sizeof(  LT_infos ));
        PyObject * Oinfos = cpyutils_getattribute(res->OParameters ,"LT_INFOS_COARSE");
	printf("inizializzo LT_INFOS_COARSE\n");// debug
	LT_pars->lt_infos_coarse->nprojs =  res->myCCspace->reading_infos.numpjs_span  ;

        initialize_LT_sparse_infos( Oinfos,  LT_pars->lt_infos_coarse     );

  LT_pars->lt_infos_coarse->lt_max_step =   cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"LT_MAX_STEP" )  );
  LT_pars->lt_infos_coarse->lt_max_step_reb =   cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"LT_MAX_STEP_REBIN" )  );
	
	
      }
      /*    */
      /* { */
      /* 	printf("inizializzo fine \n"); */
      /*   LT_pars->lt_infos_fine = (LT_infos*)malloc(sizeof(  LT_infos )); */
      /*   PyObject * Oinfos = cpyutils_getattribute(res->OParameters ,"LT_INFOS_FINE"); */
      /* 	printf("inizializzo LT_INFOS_FINE\n");// debug */
      /*   initialize_LT_sparse_infos( Oinfos,  LT_pars->lt_infos_fine     ); */
      /* 	printf("OK\n"); */
      /* } */

    }
  }


  


  res->myCCspace->params.DO_PAGANIN = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"DO_PAGANIN" )  );

  res->myCCspace->params.DO_RING_FILTER = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"DO_RING_FILTER" )  );


  res->myCCspace->params.DO_CCD_FILTER = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"DO_CCD_FILTER" )  );


  res->myCCspace->params.NO_SINOGRAM_FILTERING = cpyutils_o2i(cpyutils_getattribute(res->OParameters ,"NO_SINOGRAM_FILTERING" )  );


  fftwf_init_threads();

  printf(" exiting Cspace_new \n");

  return (PyObject*) res;
}

/* cspace.configure_readings( proj_reading_dict ) */
static PyObject *
Cspace_configure_readings(PyObject *self_a, PyObject *args)
{
  printf(" entering Cspace_configure_readings \n");

  Cspace *self;
  PyObject *Odic ;
  int  dumint,dumint2,  nchunks;
  int tryconstheader;
  PyObject *Otmp;
  int i;
  assert( (self_a)->ob_type == &Cspacetype);

  self = (Cspace *) self_a;

  if(!PyArg_ParseTuple(args,"O:Cspace_configure_readings", &Odic))
    return NULL;

  /*        "proj_reading_type"          */



  Otmp =  cpyutils_get_pydic_Oval(Odic , "proj_reading_type")  ;
  assert(PyStr_Check(Otmp));
  if   (strcmp( PyStr_AsString(Otmp), "edf")==0) {
    self->myCCspace->reading_infos.proj_reading_type = (char*)  "edf";
  } else if  (strcmp( PyStr_AsString(Otmp), "h5")==0){
    self->myCCspace->reading_infos.proj_reading_type =  (char*) "h5";
    Otmp =  cpyutils_get_pydic_Oval(Odic , "proj_h5_dsname")  ;
    assert(PyStr_Check(Otmp));
    self->myCCspace->reading_infos.proj_h5_dsname= (char*) PyStr_AsString(Otmp) ;
  } else {
    onError("proj_reading_type not .h5 not edf" );
  }


  /*        "ff_reading_type"          */

  if(self->myCCspace->params.CORRECT_FLATFIELD) {
    Otmp =  cpyutils_get_pydic_Oval(Odic , "ff_reading_type")  ;
    assert(PyStr_Check(Otmp));
    if   (strcmp( PyStr_AsString(Otmp), "edf")==0) {
      self->myCCspace->reading_infos.ff_reading_type =  (char*) "edf";
    } else if  (strcmp( PyStr_AsString(Otmp), "h5")==0){
      self->myCCspace->reading_infos.ff_reading_type = (char*)  "h5";
      Otmp =  cpyutils_get_pydic_Oval(Odic , "ff_h5_dsname")  ;
      assert(PyStr_Check(Otmp));
      self->myCCspace->reading_infos.ff_h5_dsname= (char*) PyStr_AsString(Otmp) ;
    } else {
      onError("ff_reading_type not .h5 not edf" );
    }
  }

  nchunks =   cpyutils_o2i(cpyutils_getattribute(self->OParameters ,"nchunks" )  );
  CCspace_set_nchunks(  self->myCCspace    ,  nchunks ) ;


  void **_nullpt;


#define INITIALISEARRAY(target, nome, dim, pyarraytype  )		\
  Otmp =  cpyutils_get_pydic_Oval(Odic ,  nome )  ;			\
  target =(int*) cpyutils_PyArray1D_as_array(Otmp, &dumint, pyarraytype  ); \
  assert(dumint==  dim  );

#define INITIALISEARRAY2D(target, nome, dim2, dim1, pyarraytype  )	\
  _nullpt = (void**) &target;						\
  Otmp =    cpyutils_get_pydic_Oval(Odic ,  nome )  ;			\
  *_nullpt =   cpyutils_PyArray2D_as_array(Otmp, &dumint2,  &dumint, pyarraytype  ); \
  assert(dumint2==  dim2  );						\
  assert(dumint ==  dim1  );


  // target =   cpyutils_PyArray2D_as_array(Otmp, &dumint2,  &dumint, pyarraytype  ); 



  
  /*      "proj_file_list"           */



  
  Otmp =  cpyutils_get_pydic_Oval(Odic , "proj_file_list")  ;
  
  /* fixes  ff_file_list and  ff_file_list_lenght */
  self->myCCspace->reading_infos.proj_file_list=
    cpyutils_getstringlist_from_list(Otmp,
				     &(self->myCCspace->reading_infos.proj_file_list_lenght) );


  Otmp =  cpyutils_get_pydic_Oval(Odic , "allfile_list")  ;
  self->myCCspace->reading_infos.allfile_list=
    cpyutils_getstringlist_from_list(Otmp,
				     &(self->myCCspace->reading_infos.allfile_list_lenght) );

  
  INITIALISEARRAY(  self->myCCspace->reading_infos.proj_mpi_offsets, "proj_mpi_offsets", self->nprocs, NPY_INT32);
  INITIALISEARRAY((self->myCCspace->reading_infos.proj_num_offset_list),("proj_num_offset_list"),self->myCCspace->reading_infos.nchunks,NPY_INT32);
  
  
  INITIALISEARRAY(  self->myCCspace->reading_infos.proj_mpi_numpjs , "proj_mpi_numpjs", self->nprocs, NPY_INT32 );
  
  if( self->myCCspace->params.DZPERPROJ ==0.0 ){

    INITIALISEARRAY((self->myCCspace->reading_infos.my_proj_num_list),("my_proj_num_list"),self->myCCspace->reading_infos.proj_file_list_lenght,NPY_INT32);



    INITIALISEARRAY((self->myCCspace->reading_infos.file_proj_num_list),("file_proj_num_list"),self->myCCspace->reading_infos.proj_file_list_lenght,NPY_INT32);
  } else {
    
    
    Otmp =  cpyutils_get_pydic_Oval(Odic , "my_proj_num_list"  )  ;
    self->myCCspace->reading_infos.my_proj_num_list  = (int*) cpyutils_PyArray1D_as_array(Otmp, &(dumint),   NPY_INT32);
    
    printf(" QUI CI SONO %d \n",  dumint  );
    
    
    INITIALISEARRAY((self->myCCspace->reading_infos.file_proj_num_list),("file_proj_num_list"),self->myCCspace->reading_infos.numpjs,NPY_INT32);
  }

  INITIALISEARRAY((self->myCCspace->reading_infos.tot_proj_num_list),("tot_proj_num_list"),self->myCCspace->reading_infos.numpjs_span,NPY_INT32);


  
  /*      "corr_file_list"           */
  Otmp =  cpyutils_get_pydic_Oval(Odic , "corr_file_list")  ;
  /* fixes  ff_file_list and  ff_file_list_lenght */
  self->myCCspace->reading_infos.corr_file_list=
    cpyutils_getstringlist_from_list(Otmp,
				     &(self->myCCspace->reading_infos.corr_file_list_lenght) );



  self->myCCspace->params.nprojs_span = 0;
  for(i=0; i<self->nprocs ; i++) {
    self->myCCspace->params.nprojs_span += self->myCCspace->reading_infos.proj_mpi_numpjs [i] ;
  }
  assert( self->myCCspace->params.nprojs_span == self->myCCspace->reading_infos.numpjs_span ) ;





  // printf(" NPJS : %d %d %d\n                    " , self->myCCspace->reading_infos.numpjs_span,  self->myCCspace->reading_infos.numpjs, self->myCCspace->params.nprojs_span  ) ;



  tryconstheader = cpyutils_o2i(cpyutils_getattribute(self->OParameters ,"TRYEDFCONSTANTHEADER" )  );

  if( self->myCCspace->params.STEAM_INVERTER==0) {
    CCreading_infos_PrereadHeaders(&(self->myCCspace->reading_infos),   tryconstheader,
				   self->myCCspace->reading_infos.proj_file_list, self->myCCspace->params.FILE_INTERVAL );
  }



  tryconstheader = cpyutils_o2i(cpyutils_getattribute(self->OParameters ,"TRYEDFCONSTANTHEADER" )  );

  if(self->myCCspace->reading_infos.corr_file_list_lenght)  {
    if( self->myCCspace->params.STEAM_INVERTER==0) {
      CCreading_infos_PrereadHeaders(&(self->myCCspace->reading_infos),   tryconstheader,
				     self->myCCspace->reading_infos.corr_file_list, self->myCCspace->params.FILE_INTERVAL );
    }
  }

  /*   if(!PyArray_Check(cpyutils_getattribute(self->OParameters ,"angles" ))) { */
  /*     self->myCCspace->params.do_custom_angles=0; */
  /*   } else { */
  /*     INITIALISEARRAY(self->myCCspace->params.custom_angles , "angles",self->myCCspace->params.nprojs_span , NPY_FLOAT32 ); */
  /*     self->myCCspace->params.do_custom_angles=1; */
  /*   } */
  /*      "ff_file_list"           */

  Otmp =  cpyutils_get_pydic_Oval(Odic , "ff_file_list")  ;

  /* fixes  ff_file_list and  ff_file_list_lenght */
  self->myCCspace->reading_infos.ff_file_list=
    cpyutils_getstringlist_from_list(Otmp,
				     &(self->myCCspace->reading_infos.ff_file_list_lenght) );

  INITIALISEARRAY2D(  self->myCCspace->reading_infos.ff_indexes_coefficients   , "ff_indexes_coefficients",
		      self->myCCspace->reading_infos.proj_file_list_lenght, 6, NPY_FLOAT32);
  {
    int NFF=0;
    int i;
    for( i=0; i< self->myCCspace->reading_infos.proj_file_list_lenght; i++) {
      NFF = max(NFF,self->myCCspace->reading_infos.ff_indexes_coefficients[6*i+0]   ) ;
      NFF = max(NFF,self->myCCspace->reading_infos.ff_indexes_coefficients[6*i+1]   ) ;
    }
    self->myCCspace->reading_infos.NFF = NFF+1 ; 
    
  }
  
  

  if(self->myCCspace->params.CORRECT_FLATFIELD) {
    if( self->myCCspace->params.STEAM_INVERTER==0) {
      tryconstheader = cpyutils_o2i(cpyutils_getattribute(self->OParameters ,"TRYEDFCONSTANTHEADER" )  );
      CCreading_infos_PrereadHeaders(&(self->myCCspace->reading_infos),   tryconstheader,
				     self->myCCspace->reading_infos.ff_file_list , self->myCCspace->params.FILE_INTERVAL);
    }
  }



  INITIALISEARRAY2D(  self->myCCspace->reading_infos.pos_s    , "pos_s",  nchunks ,2, NPY_INT32);
  INITIALISEARRAY2D(  self->myCCspace->reading_infos.size_s    , "size_s",  nchunks, 2, NPY_INT32 );
  INITIALISEARRAY2D(  self->myCCspace->reading_infos.pos_s_    , "pos_s_",  nchunks, 2, NPY_INT32 );
  INITIALISEARRAY2D(  self->myCCspace->reading_infos.size_s_    , "size_s_",  nchunks, 2, NPY_INT32 );


  CCspace_prepare_concurrent_ff_reading(self->myCCspace);

  // printf(" ecco i primi elementi di size_s_ %d  %d  \n", self->myCCspace->reading_infos.size_s_[0],self->myCCspace->reading_infos.size_s_[1] );
  // printf(" ecco i primi elementi di size_s  %d  %d  \n", self->myCCspace->reading_infos.size_s[0],self->myCCspace->reading_infos.size_s[1] );

  INITIALISEARRAY(  self->myCCspace->reading_infos.slices_mpi_offsets, "slices_mpi_offsets", nchunks*self->nprocs, NPY_INT32 );
  INITIALISEARRAY(  self->myCCspace->reading_infos.slices_mpi_numslices, "slices_mpi_numslices",nchunks* self->nprocs, NPY_INT32 );


  Py_INCREF( Py_None);
  printf(" exiting Cspace_configure_readings \n");

  return Py_None;
}

static PyObject *
Cspace_get_aMin (PyObject *self_a, PyObject *args)
{
  Cspace *self;
  PyObject *Oresult ;
  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;
  Oresult=PyFloat_FromDouble(self->myCCspace->aMin);
  return Oresult;
}


static PyObject *
Cspace_get_aMax (PyObject *self_a, PyObject *args)
{
  Cspace *self;
  PyObject *Oresult ;
  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;
  Oresult=PyFloat_FromDouble(self->myCCspace->aMax);
  return Oresult;
}


static PyObject *
Cspace_get_n_arraystransposed (PyObject *self_a, PyObject *args)
{
  Cspace *self;
  PyObject *Oresult ;
  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;
  Oresult=PyInt_FromLong(self->myCCspace->transposeddatatokens->ntokens);
  return Oresult;
}

static PyObject *
Cspace_get_n_arraysraw (PyObject *self_a, PyObject *args)
{
  Cspace *self;
  PyObject *Oresult ;
  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;
  Oresult=PyInt_FromLong(self->myCCspace->rawdatatokens->ntokens);
  return Oresult;
}
static PyObject *
Cspace_get_n_arraystreated (PyObject *self_a, PyObject *args)
{
  Cspace *self;
  PyObject *Oresult ;
  assert( (self_a)->ob_type == &Cspacetype);
  self = (Cspace *) self_a;
  Oresult=PyInt_FromLong(self->myCCspace->datatokens->ntokens);
  return Oresult;
}

static PyMethodDef Cspace_methods[]={
  {"configure_readings",(PyCFunction)Cspace_configure_readings , METH_VARARGS,NULL},
  {"read_chunk",(PyCFunction)Cspace_read_chunk , METH_VARARGS,NULL},
  {"preprocess_chunk",(PyCFunction) Cspace_preprocess_chunk, METH_VARARGS,NULL},
  {"InterleavedReadingPreProcessing_chunk",(PyCFunction) Cspace_InterleavedReadingPreProcessing_chunk , METH_VARARGS,NULL},
  {"reconstruct",(PyCFunction) Cspace_reconstruct_chunk, METH_VARARGS,NULL},
  {"reconstructSHARED",(PyCFunction) Cspace_reconstructSHARED_chunk, METH_VARARGS,NULL},
  {"transpose_chunk",(PyCFunction) Cspace_transpose_chunk, METH_VARARGS,NULL},
  {"dispense_chunk",(PyCFunction) Cspace_dispense_chunk, METH_VARARGS,NULL},
  {"get_n_arraysraw",(PyCFunction)Cspace_get_n_arraysraw , METH_NOARGS ,NULL},
  {"get_n_arraystreated",(PyCFunction)Cspace_get_n_arraystreated , METH_NOARGS ,NULL},
  {"get_n_arraystransposed",(PyCFunction)Cspace_get_n_arraystransposed , METH_NOARGS ,NULL},
  {"get_aMin",(PyCFunction)Cspace_get_aMin , METH_NOARGS ,NULL},
  {"get_aMax",(PyCFunction)Cspace_get_aMax , METH_NOARGS ,NULL},
  {"getSaturations",(PyCFunction)Cspace_getSaturations , METH_VARARGS ,NULL},
  { NULL, NULL}
  /*   {"calcSlices",(PyCFunction) Cspace_calcSlices, METH_VARARGS,Cspace_calcSlices_doc}, */
  /*   {"calcMedian",(PyCFunction) Cspace_calcMedian, METH_VARARGS,Cspace_calcMedian_doc}, */
  /*{"calcSlicesMemory",(PyCFunction) Cspace_calcSlicesMemory, METH_VARARGS,Cspace_calcSlicesMemory_doc}, */
  /*   {"setFilterFunct",(PyCFunction) Cspace_SetFilterFunct, METH_VARARGS,Cspace_SetFilterFunct_doc}, */
  /*   { "setThetaOffset", (PyCFunction) Cspace_setthetaoffset  , METH_VARARGS, NULL   } , */
  /*   {"close", (PyCFunction) Cspace_close,  METH_VARARGS, NULL    }, */
};

/* static struct memberlist Cspace_memberlist[]={ */
/*   { NULL } */
/* }; */

static PyMethodDef Cspace_functions[] = {
  {"Cspace", (PyCFunction) Cspace_new, METH_VARARGS, NULL },
  { NULL, NULL}
};

static PyObject *
Cspace_getattr(Cspace *self, char *attr)
{
  PyObject *res;

#if PY_MAJOR_VERSION >= 3
  res = PyObject_GenericGetAttr( (PyObject *)   self, PyUnicode_FromString(attr)) ; 
#else
  res= Py_FindMethod(Cspace_methods, (PyObject*) self, attr);
#endif
    
  if(NULL !=res)
    return res;
  else {
    return Py_None;
    /* PyErr_Clear(); */
    /* return PyMember_Get((char*) self,Cspace_memberlist, attr); */
  }
}

#if PY_MAJOR_VERSION >= 3

/* static PyTypeObject MyCspacetype = { */
/*   PyObject_HEAD_INIT(NULL) */
/*   "Cspace", */
/*   sizeof(Cspace), */
/*   0, */
/*   (destructor) Cspace_dealloc, */
/*   0, */
/*   (getattrfunc) Cspace_getattr, */
/* }; */

static PyTypeObject MyCspacetype = {
  PyVarObject_HEAD_INIT(NULL,0)
  .tp_name = "Cspace.Cspace",
  .tp_doc = "Cspace",
  .tp_basicsize = sizeof(Cspace),
  .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
  .tp_new   = (newfunc) Cspace_new,
  .tp_dealloc = (destructor) Cspace_dealloc,
  .tp_methods = Cspace_methods
};


static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,  /* m_base */
    "Cspace",                 /* m_name */
    NULL,                   /* m_doc */
    -1 // ,                     /* m_size */
    //  Cspace_functions           /* m_methods */
};
#else
static PyTypeObject MyCspacetype = {
  PyObject_HEAD_INIT(&PyType_Type)
  0,
  "Cspace",
  sizeof(Cspace),
  0,
  (destructor) Cspace_dealloc,
  0,
  (getattrfunc) Cspace_getattr,
};


#endif

#if PY_MAJOR_VERSION >= 3
   #define INITERROR return NULL
   PyObject * PyInit_Cspace(void)
#else
  #define INITERROR return
  void   initCspace(void)
#endif
{

  Cspacetype = MyCspacetype;
  
  PyObject *m, *d;

#if PY_MAJOR_VERSION >= 3

  if (PyType_Ready(&Cspacetype) < 0)
    return NULL;
  m = PyModule_Create(&moduledef);
  Py_INCREF(&Cspacetype);
  PyModule_AddObject(m, "Cspace", (PyObject *) &Cspacetype);
  
#else
  m = Py_InitModule("Cspace", Cspace_functions);

  if (m == NULL)
    INITERROR;
  d = PyModule_GetDict(m);
  ErrorObject = Py_BuildValue("s","Cspace.error");
  PyDict_SetItemString(d,"error", ErrorObject);
  if(PyErr_Occurred())
    Py_FatalError("can't initialize module Cspace");

#endif





#ifdef import_array
  import_array();
#endif


#if PY_MAJOR_VERSION >= 3
    return m;
#endif
  
 
}
