183 lines
6.5 KiB
Cython
183 lines
6.5 KiB
Cython
|
#cython: language_level=3
|
||
|
#
|
||
|
# Author: Joshua Cohen
|
||
|
# Copyright 2017
|
||
|
#
|
||
|
|
||
|
#################################################################
|
||
|
|
||
|
cdef extern from "Poly2d.h" namespace "isceLib":
|
||
|
cdef cppclass Poly2d:
|
||
|
int azimuthOrder
|
||
|
int rangeOrder
|
||
|
double azimuthMean
|
||
|
double rangeMean
|
||
|
double azimuthNorm
|
||
|
double rangeNorm
|
||
|
double *coeffs
|
||
|
|
||
|
Poly2d() except +
|
||
|
Poly2d(int,int,double,double,double,double) except +
|
||
|
Poly2d(int,int,double,double,double,double,double*) except +
|
||
|
Poly2d(const Poly2d&) except +
|
||
|
int isNull()
|
||
|
void resetCoeffs()
|
||
|
void setCoeff(int,int,double)
|
||
|
double getCoeff(int,int)
|
||
|
double eval(double,double)
|
||
|
|
||
|
cdef class PyPoly2d:
|
||
|
cdef Poly2d c_poly2d
|
||
|
|
||
|
def __cinit__(self, a=None, b=None, c=None, d=None, e=None, f=None, g=None):
|
||
|
if (g): # init with coeffs
|
||
|
if (a and b):
|
||
|
self.c_poly2d.azimuthOrder = a # Have to avoid the setters due to the 2D nature
|
||
|
self.c_poly2d.rangeOrder = b
|
||
|
self.resetCoeffs()
|
||
|
self.coeffs = g
|
||
|
else:
|
||
|
print("Error: Cannot init Poly2d with coefficients without specifying range and azimuth order.")
|
||
|
self.resetCoeffs()
|
||
|
self.coeffs = []
|
||
|
self.azimuthMean = c
|
||
|
self.rangeMean = d
|
||
|
self.azimuthNorm = e
|
||
|
self.rangeNorm = f
|
||
|
elif (a): # Init without coeffs
|
||
|
if (a and b):
|
||
|
self.c_poly2d.azimuthOrder = a
|
||
|
self.c_poly2d.rangeOrder = b
|
||
|
elif (a):
|
||
|
self.c_poly2d.azimuthOrder = a
|
||
|
self.c_poly2d.rangeOrder = 0
|
||
|
else:
|
||
|
self.c_poly2d.azimuthOrder = 0
|
||
|
self.c_poly2d.rangeOrder = b
|
||
|
self.azimuthMean = c
|
||
|
self.rangeMean = d
|
||
|
self.azimuthNorm = e
|
||
|
self.rangeNorm = f
|
||
|
self.resetCoeffs()
|
||
|
|
||
|
@property
|
||
|
def azimuthOrder(self):
|
||
|
return self.c_poly2d.azimuthOrder
|
||
|
@azimuthOrder.setter
|
||
|
def azimuthOrder(self, int a):
|
||
|
# Need a better way to do this...
|
||
|
if (a < 0):
|
||
|
return
|
||
|
if (self.rangeOrder == -1): # only on empty constructor
|
||
|
self.c_poly2d.azimuthOrder = a
|
||
|
else:
|
||
|
c = self.coeffs
|
||
|
for i in range((a-self.azimuthOrder)*(self.rangeOrder+1)):
|
||
|
c.append(0.)
|
||
|
nc = []
|
||
|
for i in range((a+1)*(self.rangeOrder+1)):
|
||
|
nc.append(c[i])
|
||
|
self.c_poly2d.azimuthOrder = a
|
||
|
self.resetCoeffs()
|
||
|
self.coeffs = nc
|
||
|
@property
|
||
|
def rangeOrder(self):
|
||
|
return self.c_poly2d.rangeOrder
|
||
|
@rangeOrder.setter
|
||
|
def rangeOrder(self, int a):
|
||
|
# Need a better way to do this...
|
||
|
if (a < 0):
|
||
|
return
|
||
|
if (self.azimuthOrder == -1):
|
||
|
self.c_poly2d.rangeOrder = a
|
||
|
else:
|
||
|
c = self.coeffs
|
||
|
nc = []
|
||
|
# Cleanest is to first form 2D array of coeffs from 1D
|
||
|
for i in range(self.azimuthOrder+1):
|
||
|
ncs = []
|
||
|
for j in range(self.rangeOrder+1):
|
||
|
ncs.append(c[i*(self.rangeOrder+1)+j])
|
||
|
nc.append(ncs)
|
||
|
# nc is now the 2D reshape of coeffs
|
||
|
for i in range(self.azimuthOrder+1): # Go row-by-row...
|
||
|
for j in range(a-self.rangeOrder): # Add 0s to each row (if
|
||
|
nc[i].append(0.) # a > self.rangeOrder)
|
||
|
self.c_poly2d.rangeOrder = a
|
||
|
self.resetCoeffs()
|
||
|
c = []
|
||
|
for i in range(self.azimuthOrder+1):
|
||
|
for j in range(self.rangeOrder+1):
|
||
|
c.append(nc[i][j])
|
||
|
self.coeffs = c
|
||
|
@property
|
||
|
def azimuthMean(self):
|
||
|
return self.c_poly2d.azimuthMean
|
||
|
@azimuthMean.setter
|
||
|
def azimuthMean(self, double a):
|
||
|
self.c_poly2d.azimuthMean = a
|
||
|
@property
|
||
|
def rangeMean(self):
|
||
|
return self.c_poly2d.rangeMean
|
||
|
@rangeMean.setter
|
||
|
def rangeMean(self, double a):
|
||
|
self.c_poly2d.rangeMean = a
|
||
|
@property
|
||
|
def azimuthNorm(self):
|
||
|
return self.c_poly2d.azimuthNorm
|
||
|
@azimuthNorm.setter
|
||
|
def azimuthNorm(self, double a):
|
||
|
self.c_poly2d.azimuthNorm = a
|
||
|
@property
|
||
|
def rangeNorm(self):
|
||
|
return self.c_poly2d.rangeNorm
|
||
|
@rangeNorm.setter
|
||
|
def rangeNorm(self, double a):
|
||
|
self.c_poly2d.rangeNorm = a
|
||
|
@property
|
||
|
def coeffs(self):
|
||
|
a = []
|
||
|
if (self.isNull() == 1):
|
||
|
return a
|
||
|
for i in range((self.azimuthOrder+1)*(self.rangeOrder+1)):
|
||
|
a.append(self.c_poly2d.coeffs[i])
|
||
|
return a
|
||
|
@coeffs.setter
|
||
|
def coeffs(self, a):
|
||
|
if ((self.azimuthOrder+1)*(self.rangeOrder+1) != len(a)):
|
||
|
print("Error: Invalid input size (expected 1D list of length "+str(self.azimuthOrder+1)+"*"+str(self.rangeOrder+1)+")")
|
||
|
return
|
||
|
if (self.isNull() == 1): # Only happens if you try to immediately set coefficients after calling the empty constructor
|
||
|
print("Warning: Memory was not malloc'd for coefficients. Range/azimuth order cannot be inferred, so coefficients will not be set.")
|
||
|
return
|
||
|
for i in range((self.azimuthOrder+1)*(self.rangeOrder+1)):
|
||
|
self.c_poly2d.coeffs[i] = a[i]
|
||
|
def copy(self, poly):
|
||
|
try:
|
||
|
self.azimuthOrder = poly.azimuthOrder
|
||
|
self.rangeOrder = poly.rangeOrder
|
||
|
self.azimuthMean = poly.azimuthMean
|
||
|
self.rangeMean = poly.rangeMean
|
||
|
self.azimuthNorm = poly.azimuthNorm
|
||
|
self.rangeNorm = poly.rangeNorm
|
||
|
self.resetCoeffs()
|
||
|
self.coeffs = poly.coeffs
|
||
|
except:
|
||
|
print("Error: Object passed in to copy is not of type PyPoly2d.")
|
||
|
def dPrint(self):
|
||
|
print("AzimuthOrder = "+str(self.azimuthOrder)+", rangeOrder = "+str(self.rangeOrder)+", azimuthMean = "+str(self.azimuthMean)+", rangeMean = "+str(self.rangeMean)+
|
||
|
", azimuthNorm = "+str(self.azimuthNorm)+", rangeNorm = "+str(self.rangeNorm)+", coeffs = "+str(self.coeffs))
|
||
|
|
||
|
def isNull(self):
|
||
|
return self.c_poly2d.isNull()
|
||
|
def resetCoeffs(self):
|
||
|
self.c_poly2d.resetCoeffs()
|
||
|
def setCoeff(self, int a, int b, double c):
|
||
|
self.c_poly2d.setCoeff(a,b,c)
|
||
|
def getCoeff(self, int a, int b):
|
||
|
return self.c_poly2d.getCoeff(a,b)
|
||
|
def eval(self, double a, double b):
|
||
|
return self.c_poly2d.eval(a,b)
|
||
|
|
||
|
|