~i-martividal/uvmultifit/trunk-1

« back to all changes in this revision

Viewing changes to _uvmultimodel.cpp

  • Committer: imarvi2 at uv
  • Date: 2024-05-01 07:05:47 UTC
  • Revision ID: imarvi2@uv.es-20240501070547-36ke1vn3ysnlahj4
Version 3.1. Ported to Python3

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
#
6
6
# Copyright (c) Ivan Marti-Vidal 2012. 
7
7
#               EU ALMA Regional Center. Nordic node.
 
8
# Copyright (c) Ivan Marti-Vidal 2024
 
9
#               Universitat de Valencia (Spain)
8
10
#
9
11
# This program is free software; you can redistribute it and/or modify
10
12
# it under the terms of the GNU General Public License as published by
58
60
 
59
61
 
60
62
#include <Python.h>
 
63
 
 
64
 
 
65
// compiler warning that we use a deprecated NumPy API
 
66
// #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
 
67
//#define NO_IMPORT_ARRAY
 
68
#if PY_MAJOR_VERSION >= 3
 
69
#define NPY_NO_DEPRECATED_API 0x0
 
70
#endif
 
71
#include <numpy/npy_common.h>
61
72
#include <numpy/arrayobject.h>
 
73
 
62
74
#include <pthread.h>
63
75
#include <gsl/gsl_sf_bessel.h>
64
76
#include <stdio.h>  
79
91
 
80
92
 
81
93
 
 
94
 
 
95
 
 
96
 
 
97
// cribbed from SWIG machinery
 
98
#if PY_MAJOR_VERSION >= 3
 
99
#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
 
100
#define PyInt_Check(x) PyLong_Check(x)
 
101
#define PyInt_AsLong(x) PyLong_AsLong(x)
 
102
#define PyInt_FromLong(x) PyLong_FromLong(x)
 
103
#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
 
104
#define PyString_Check(name) PyBytes_Check(name)
 
105
#define PyString_FromString(x) PyUnicode_FromString(x)
 
106
#define PyString_Format(fmt, args)  PyUnicode_Format(fmt, args)
 
107
//#define PyString_AsString(str) PyBytes_AsString(str)
 
108
#define PyString_Size(str) PyBytes_Size(str)
 
109
#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
 
110
#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
 
111
#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
 
112
#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
 
113
// For PyArray_FromDimsAndData -> PyArray_SimpleNewFromData
 
114
//#define INTEGER long
 
115
//#define INTEGERCAST  (const npy_intp*)
 
116
//#else
 
117
// For PyArray_FromDimsAndData -> PyArray_SimpleNewFromData
 
118
//#define INTEGER int
 
119
//#define INTEGERCAST (long int *)
 
120
#endif
 
121
// and after some hacking
 
122
#if PY_MAJOR_VERSION >= 3
 
123
#define PyString_AsString(obj) PyUnicode_AsUTF8(obj)
 
124
#endif
 
125
 
 
126
 
 
127
 
 
128
 
 
129
 
 
130
 
 
131
 
82
132
/* Docstrings */
83
133
static char module_docstring[] =
84
134
    "This module provides an interface for least-square visibility fitting.";
133
183
};
134
184
 
135
185
 
 
186
// normally abort() is called on problems, which breaks CASA.
 
187
// here we report and save the error condition which can be
 
188
// noticed for a cleaner exit.
 
189
//int gsl_death_by = GSL_SUCCESS;
 
190
//static void gsl_death(const char * reason, const char * file,
 
191
//    int line, int gsl_errno) {
 
192
//    // stderr does not end up synchronized with stdout
 
193
//    printf("GSL Death by '%s' in file %s at line %d: GSL Error %d\n",
 
194
//        reason, file, line, gsl_errno);
 
195
//    fflush(stdout); std::cout << std::flush;
 
196
//    gsl_death_by = gsl_errno;
 
197
//}
 
198
 
 
199
 
 
200
 
 
201
 
 
202
 
 
203
 
136
204
 
137
205
typedef std::complex<double> cplx64;
138
206
 
217
285
 
218
286
 
219
287
/* Initialize the module */
 
288
 
 
289
#if PY_MAJOR_VERSION >= 3
 
290
static struct PyModuleDef pc_module_def = {
 
291
    PyModuleDef_HEAD_INIT,
 
292
    "_uvmultimodel",         /* m_name */
 
293
    module_docstring,       /* m_doc */
 
294
    -1,                     /* m_size */
 
295
    module_methods,         /* m_methods */
 
296
    NULL,NULL,NULL,NULL     /* m_reload, m_traverse, m_clear, m_free */
 
297
};
 
298
PyMODINIT_FUNC PyInit__uvmultimodel(void)
 
299
{
 
300
    PyObject *m = PyModule_Create(&pc_module_def);
 
301
  //  import_array();
 
302
  //  (void)gsl_set_error_handler(gsl_death);
 
303
 
 
304
//////////////////////
 
305
// Initiate variables with dummy values:
 
306
    NCPU = 0; Nspw = 0; npar = -1; Nants = 0; ncomp = -1; Nbas = 0;
 
307
    master.t0 = new int[1];
 
308
    master.t1 = new int[1];
 
309
 
 
310
    return(m);
 
311
}
 
312
 
 
313
 
 
314
 
 
315
#else
 
316
 
220
317
PyMODINIT_FUNC init_uvmultimodel(void)
221
318
{
222
319
    PyObject *m = Py_InitModule3("_uvmultimodel", module_methods, module_docstring);
223
320
    if (m == NULL)
224
321
        return;
225
322
 
226
 
 
227
 
 
228
 
 
229
323
//////////////////////
230
324
// Initiate variables with dummy values:
231
325
    NCPU = 0; Nspw = 0; npar = -1; Nants = 0; ncomp = -1; Nbas = 0;
234
328
 
235
329
////////////////////
236
330
 
237
 
 
238
 
 
239
331
    /* Load `numpy` functionality. */
240
332
    import_array();
241
333
}
242
334
 
243
 
 
244
 
 
245
 
 
246
 
 
247
 
 
248
 
 
 
335
#endif
 
336
 
 
337
 
 
338
 
 
339
 
 
340
/* Clears pointers to the data
 
341
WARNING: In principle, this shouldn't be done, since the
 
342
data in these pointers may still be used by Python!!
 
343
*/
249
344
void clearData(){
250
345
 
 
346
/*
251
347
      int i,j;
252
 
 
253
348
      delete vis.ants[0];
254
349
      delete vis.ants[1];
255
350
      delete vis.uv[0];
276
371
    };
277
372
 
278
373
 
279
 
 
280
374
if(Nspw > 0){
281
375
    delete vis.nnu;
282
376
    delete vis.nt;
283
377
};
 
378
*/
284
379
 
285
380
return;
286
381
 
288
383
 
289
384
 
290
385
 
291
 
 
 
386
/* WARNING! There are pointers here that may still
 
387
be used by Python! */
292
388
void clearModel(){
293
389
  int i;
294
390
 
295
391
    if(isModel){
296
 
      delete mod.vars;
297
 
      delete mod.fixp;
298
 
      delete mod.parAnt;
299
 
      delete mod.nparAnt;
300
 
      delete mod.models;
 
392
//      delete mod.vars;
 
393
//      delete mod.fixp;
 
394
//      delete mod.parAnt;
 
395
//      delete mod.nparAnt;
 
396
//      delete mod.models;
301
397
      delete mod.closBufferWgt;
302
398
      delete mod.closBuffer;
303
399
      delete mod.closBufferAbs;
316
412
      delete mod.BasIdx; delete mod.phaseClosIdx; delete mod.ampClosIdx;
317
413
    };
318
414
 
 
415
isModel = false;
 
416
 
319
417
return;
320
418
 
321
419
};
1388
1486
 
1389
1487
    /* Interprete the input objects as numpy arrays. */
1390
1488
 
1391
 
  //  printf("\n     setData. Ants: %i \n\n",Nants);
1392
 
 
1393
 
//    if(IF==0){clearData();};
1394
 
 
1395
 
 
1396
 
    vis.ants[0][IF] = (int *)PyArray_DATA(PyArray_FROM_OTF(ant1l, NPY_INT, NPY_IN_ARRAY));
1397
 
    vis.ants[1][IF] = (int *)PyArray_DATA(PyArray_FROM_OTF(ant2l, NPY_INT, NPY_IN_ARRAY));
1398
 
 
1399
 
    vis.dtArray[IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(tArr, NPY_DOUBLE, NPY_IN_ARRAY));
1400
 
    vis.dtIndex[IF] = (int *)PyArray_DATA(PyArray_FROM_OTF(tIdx, NPY_INT, NPY_IN_ARRAY));
1401
 
 
1402
 
    vis.uv[0][IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(pu, NPY_DOUBLE, NPY_IN_ARRAY));
1403
 
    vis.uv[1][IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(pv, NPY_DOUBLE, NPY_IN_ARRAY));
1404
 
    vis.uv[2][IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(pw, NPY_DOUBLE, NPY_IN_ARRAY));
1405
 
 
1406
 
    vis.wgt[0][IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(pwgt, NPY_DOUBLE, NPY_IN_ARRAY));
1407
 
 
1408
 
    vis.ObsVis[IF] = (cplx64 *)PyArray_DATA(PyArray_FROM_OTF(preal, NPY_COMPLEX128, NPY_IN_ARRAY));
1409
 
 
1410
 
 
1411
 
    mod.ModVis[IF] = (cplx64 *)PyArray_DATA(PyArray_FROM_OTF(poreal, NPY_COMPLEX128, NPY_IN_ARRAY));
1412
 
 
1413
 
    vis.freqs[IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(pfreqs, NPY_DOUBLE, NPY_IN_ARRAY));
1414
 
 
1415
 
    vis.fittable[IF] = (int *)PyArray_DATA(PyArray_FROM_OTF(pfittable, NPY_INT, NPY_IN_ARRAY));
1416
 
    vis.wgt[1][IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(pwgtcorr, NPY_DOUBLE, NPY_IN_ARRAY));
1417
 
 
1418
 
    vis.isGain[IF] = (int *)PyArray_DATA(PyArray_FROM_OTF(iG, NPY_INT, NPY_IN_ARRAY));
1419
 
 
1420
 
 
1421
 
    vis.dt[IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(dtime, NPY_DOUBLE, NPY_IN_ARRAY));
1422
 
 
1423
 
    vis.RAshift[IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(RAoffset, NPY_DOUBLE, NPY_IN_ARRAY));
1424
 
 
1425
 
    vis.Decshift[IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(Decoffset, NPY_DOUBLE, NPY_IN_ARRAY));
1426
 
 
1427
 
    vis.Stretch[IF] = (double *)PyArray_DATA(PyArray_FROM_OTF(Stretchoff, NPY_DOUBLE, NPY_IN_ARRAY));
 
1489
 
 
1490
    vis.ants[0][IF] = (int *)PyArray_DATA(ant1l);
 
1491
    vis.ants[1][IF] = (int *)PyArray_DATA(ant2l);
 
1492
 
 
1493
 
 
1494
    vis.dtArray[IF] = (double *)PyArray_DATA(tArr);
 
1495
    vis.dtIndex[IF] = (int *)PyArray_DATA(tIdx);
 
1496
 
 
1497
    vis.uv[0][IF] = (double *)PyArray_DATA(pu);
 
1498
    vis.uv[1][IF] = (double *)PyArray_DATA(pv);
 
1499
    vis.uv[2][IF] = (double *)PyArray_DATA(pw);
 
1500
 
 
1501
    vis.wgt[0][IF] = (double *)PyArray_DATA(pwgt);
 
1502
    vis.ObsVis[IF] = (cplx64 *)PyArray_DATA(preal);
 
1503
 
 
1504
    mod.ModVis[IF] = (cplx64 *)PyArray_DATA(poreal);
 
1505
 
 
1506
    vis.freqs[IF] = (double *)PyArray_DATA(pfreqs);
 
1507
 
 
1508
    vis.fittable[IF] = (int *)PyArray_DATA(pfittable);
 
1509
    vis.wgt[1][IF] = (double *)PyArray_DATA(pwgtcorr);
 
1510
 
 
1511
    vis.isGain[IF] = (int *)PyArray_DATA(iG);
 
1512
 
 
1513
 
 
1514
    vis.dt[IF] = (double *)PyArray_DATA(dtime);
 
1515
 
 
1516
    vis.RAshift[IF] = (double *)PyArray_DATA(RAoffset);
 
1517
 
 
1518
    vis.Decshift[IF] = (double *)PyArray_DATA(Decoffset);
 
1519
 
 
1520
    vis.Stretch[IF] = (double *)PyArray_DATA(Stretchoff);
1428
1521
 
1429
1522
    vis.nt[IF] = PyArray_DIM(preal,0);
1430
1523
    vis.nnu[IF] = PyArray_DIM(preal,1);
1485
1578
    if(NCPU>1 && (doAmpClos || doPhClos)){printf("FAILED Closures cannot be used if NCPU>1!\n"); fflush(stdout); PyObject *ret = Py_BuildValue("i",-2); return ret;};
1486
1579
 
1487
1580
 
1488
 
    mod.models = (int *)PyArray_DATA(PyArray_FROM_OTF(modArr, NPY_INT32, NPY_IN_ARRAY));
1489
 
    mod.Hessian = (double *)PyArray_DATA(PyArray_FROM_OTF(HessArr, NPY_DOUBLE, NPY_IN_ARRAY));
1490
 
    mod.Gradient = (double *)PyArray_DATA(PyArray_FROM_OTF(GradArr, NPY_DOUBLE, NPY_IN_ARRAY));
1491
 
    mod.dpar = (double *)PyArray_DATA(PyArray_FROM_OTF(dparArr, NPY_DOUBLE, NPY_IN_ARRAY));
1492
 
    mod.muRA = (double *)PyArray_DATA(PyArray_FROM_OTF(propRA, NPY_DOUBLE, NPY_IN_ARRAY));
1493
 
    mod.muDec = (double *)PyArray_DATA(PyArray_FROM_OTF(propDec, NPY_DOUBLE, NPY_IN_ARRAY));
1494
 
    vis.phaseCenter = (double *)PyArray_DATA(PyArray_FROM_OTF(refpos, NPY_DOUBLE, NPY_IN_ARRAY));
1495
 
    mod.triSpec = (int *)PyArray_DATA(PyArray_FROM_OTF(triSpec, NPY_INT32, NPY_IN_ARRAY));
 
1581
    mod.models = (int *)PyArray_DATA(modArr);
 
1582
    mod.Hessian = (double *)PyArray_DATA(HessArr);
 
1583
    mod.Gradient = (double *)PyArray_DATA(GradArr);
 
1584
    mod.dpar = (double *)PyArray_DATA(dparArr);
 
1585
    mod.muRA = (double *)PyArray_DATA(propRA);
 
1586
    mod.muDec = (double *)PyArray_DATA(propDec);
 
1587
    vis.phaseCenter = (double *)PyArray_DATA(refpos);
 
1588
    mod.triSpec = (int *)PyArray_DATA(triSpec);
1496
1589
 
1497
1590
    cosDecRef = cos(vis.phaseCenter[1]);
1498
1591
    sinDecRef = sin(vis.phaseCenter[1]);
1629
1722
 
1630
1723
    for (i=0;i<Nants;i++){
1631
1724
      mod.nparAnt[i] = PyArray_DIM(PyList_GetItem(parDep,i),0);
1632
 
      mod.parAnt[i] = (int *)PyArray_DATA(PyArray_FROM_OTF(PyList_GetItem(parDep,i), NPY_INT32, NPY_IN_ARRAY));
 
1725
      mod.parAnt[i] = (int *)PyArray_DATA(PyList_GetItem(parDep,i));
1633
1726
    };
1634
1727
 
1635
1728
 
1643
1736
        mod.Gain[IF][j] = new cplx64*[mod.nparAnt[j]];
1644
1737
        for (i=0;i<mod.nparAnt[j];i++){
1645
1738
          tempArr = PyList_GetItem(PyList_GetItem(PyList_GetItem(aG,IF),j),i);
1646
 
          mod.Gain[IF][j][i] = (cplx64 *)PyArray_DATA(PyArray_FROM_OTF(tempArr, NPY_COMPLEX128, NPY_IN_ARRAY));
 
1739
          mod.Gain[IF][j][i] = (cplx64 *)PyArray_DATA(tempArr);
1647
1740
        };
1648
1741
      };
1649
1742
 
1665
1758
 
1666
1759
    for (i=0; i<(npar+1); i++) {
1667
1760
      tempArr = PyList_GetItem(VarArr,i);
1668
 
      mod.vars[i] = (double *)PyArray_DATA(PyArray_FROM_OTF(tempArr, NPY_DOUBLE, NPY_IN_ARRAY));
 
1761
      mod.vars[i] = (double *)PyArray_DATA(tempArr);
1669
1762
    };
1670
1763
 
1671
1764
 
1672
1765
    for (i=0; i<(npar+1); i++) {
1673
1766
      tempArr = PyList_GetItem(FixArr,i);
1674
 
      mod.fixp[i] = (double *)PyArray_DATA(PyArray_FROM_OTF(tempArr, NPY_DOUBLE, NPY_IN_ARRAY));
 
1767
      mod.fixp[i] = (double *)PyArray_DATA(tempArr);
1675
1768
    };
1676
1769
 
1677
1770
 
1873
1966
  int IFFit, refant, doModel, doGlobal;
1874
1967
  int ErrStat = 0; // To track errors in GFF (not implemented)
1875
1968
 
1876
 
PyObject *ret;
 
1969
  PyObject *ret, *gainList;
1877
1970
 
1878
 
    if (!PyArg_ParseTuple(args, "iiii",&IFFit, &refant, &doModel, &doGlobal)){printf("FAILED QuinnFringe!\n"); fflush(stdout);  ret = Py_BuildValue("i",-1); return ret;};
 
1971
    if (!PyArg_ParseTuple(args, "iiiiO",&IFFit, &refant, &doModel, &doGlobal, &gainList)){printf("FAILED QuinnFringe!\n"); fflush(stdout);  ret = Py_BuildValue("i",-1); return ret;};
1879
1972
 
1880
1973
 
1881
1974
#if QUINN_FITTER == 0
1890
1983
 
1891
1984
// Return the gains:
1892
1985
 
1893
 
double *Rates = new double[Nants]; 
1894
 
double *Delays = new double[Nants];
1895
 
double *Phases = new double[Nants];
 
1986
//double *Rates = new double[Nants]; 
 
1987
//double *Delays = new double[Nants];
 
1988
//double *Phases = new double[Nants];
 
1989
 
 
1990
double *Delays = (double *)PyArray_DATA(PyList_GetItem(gainList,0));
 
1991
double *Rates = (double *)PyArray_DATA(PyList_GetItem(gainList,1));
 
1992
double *Phases = (double *)PyArray_DATA(PyList_GetItem(gainList,2));
1896
1993
double *Bins = new double[2];
1897
1994
 
1898
1995
ErrStat = FringeFit->getRates(Rates);
1900
1997
ErrStat = FringeFit->getPhases(Phases);
1901
1998
ErrStat = FringeFit->getBins(Bins);
1902
1999
 
1903
 
PyObject *PyRate, *PyDelay, *PyPhase;
 
2000
//PyObject *PyRate, *PyDelay, *PyPhase;
1904
2001
 
1905
 
npy_intp Dims[1]; Dims[0] = Nants;
 
2002
npy_intp Dims[1];
 
2003
//int *Dims = new int[1];
 
2004
Dims[0] = Nants;
1906
2005
 
1907
2006
//printf("\nNants: %i  DIMS:  %i/%.3e/%.3e \n",Nants,Dims[0], Bins[0],Bins[1]);
1908
2007
 
1909
 
PyRate = PyArray_SimpleNewFromData(1, Dims, NPY_FLOAT64, (void *) Rates);
1910
 
PyDelay = PyArray_SimpleNewFromData(1, Dims, NPY_FLOAT64, (void *) Delays);
1911
 
PyPhase = PyArray_SimpleNewFromData(1, Dims, NPY_FLOAT64, (void *) Phases);
 
2008
//PyRate = PyArray_SimpleNewFromData(1, Dims, NPY_FLOAT64, (void *) Rates);
 
2009
//PyDelay = PyArray_SimpleNewFromData(1, Dims, NPY_FLOAT64, (void *) Delays);
 
2010
//PyPhase = PyArray_SimpleNewFromData(1, Dims, NPY_FLOAT64, (void *) Phases);
1912
2011
 
1913
2012
//printf("\n Ant 1: %.4e %.4e %.4e\n", Rates[0], Delays[0], Phases[0]);
1914
2013
 
1915
 
ret = Py_BuildValue("[O,O,O,d,d]",PyDelay,PyRate,PyPhase,Bins[0],Bins[1]);
 
2014
//ret = Py_BuildValue("[O,O,O,d,d]",PyDelay,PyRate,PyPhase,Bins[0],Bins[1]);
 
2015
ret = Py_BuildValue("[d,d]",Bins[0],Bins[1]);
1916
2016
 
1917
2017
delete FringeFit;
1918
2018