diff --git a/src/yapsut/__init__.py b/src/yapsut/__init__.py index e184ff0ad5132125a6781aa2c57bb8dd1f599403..2a287eaa0afeb11fcf474033f7e042a61215a696 100644 --- a/src/yapsut/__init__.py +++ b/src/yapsut/__init__.py @@ -9,3 +9,6 @@ from .files import moveFile2backup from .wavenumber_base import wavenumber_base from .profiling import timer,timerDict from .struct import struct +#from import .grep +#import .intervalls + diff --git a/src/yapsut/dev/README.md b/src/yapsut/dev/README.md new file mode 100644 index 0000000000000000000000000000000000000000..66e644424372a7e9ecfa4c427b5a040435ac93b6 --- /dev/null +++ b/src/yapsut/dev/README.md @@ -0,0 +1 @@ +dev/ contains libraries under development / importing in yapsut diff --git a/src/yapsut/dev/grid2d.py b/src/yapsut/dev/grid2d.py new file mode 100644 index 0000000000000000000000000000000000000000..55a1d6e746e614b3234c91dabf4d0183620b7808 --- /dev/null +++ b/src/yapsut/dev/grid2d.py @@ -0,0 +1,2088 @@ +__version__="""M.Maris, 1.3 - - 27 Nov 2012 - 26 Dec 2016 -""" +__DESCRIPTION__=""" +A grid 2d is a 2x2 array representing a grid +At the moment no DS9 support is directly provided + +Private: _PIXEL_LIST a list of pixels and _CENTER for the center of a map + +""" + +class fast_histogram : + def __init__(self,x,levels=None,vmin=None,vmax=None,finite=False,nan=False) : + """returns the unique values of an array x and their counts""" + import numpy as np + a=np.sort(x.reshape(x.size)) + self.vmin = a[0] if vmin == None else vmin + self.vmax = a[-1] if vmax == None else vmax + if levels == None : + self.u=np.unique(a) + self.step=None + elif type(levels) == type(0) : + self.step = float(vmax-vmin)/float(levels) + self.u=np.arange(self.vmin,self.vmax+self.step,self.step) + self.idx=np.zeros(len(self.u)) + self.nsamples=len(a) + i=-1 + for v in self.u : + i+=1 + self.idx[i]=a.searchsorted(v) + self.levels=(self.u[1:]+self.u[:-1])*0.5 + self.dn=self.idx[1:]-self.idx[:-1] + self.dn[-1]=self.nsamples-self.idx[-1]+1 + self.df=self.dn/float(self.nsamples) + self.N=self.dn.cumsum() + self.F=self.N/float(self.nsamples) + def midlevels(self) : + return (self.u[1:]+self.u[:-1])*0.5 + def width(self) : + return (self.u[1:]-self.u[:-1]) + def polygonal(self) : + pass + +def Error(msg) : return Exception(msg) + +class _PIXEL_LIST : + def __init__(self,irows,icols) : + """A pixel list for given indexes of rows and columns""" + import numpy as np + #if len(irows) != len(icols) : + #raise "Unequal irows, icols" + #return None + self.irow = np.array(irows) + self.icol = np.array(icols) + def __len__(self) : + return len(self.irow) + def __getitem__(self,idx) : + return (self.irow[idx],self.icol[idx]) + def dump(self,output) : + import pickle + pickle.dump(self.__dict__,output) + def load(self,Input) : + import pickle + self.__dict__=pickle.load(Input) + +class _CENTER : + def __init__(self,center_long_deg,center_colat_deg,Input=None) : + """Center of a map""" + import _ANGLE + import pickle + if Input == None : + self.long = _ANGLE(deg=center_long_deg) + self.colat = _ANGLE(deg=center_colat_deg) + else : + self.__dict__=pickle.load(Input) + def dump(self,output) : + import pickle + pickle.dump(output,self.__dict__) + def load(self,Input) : + import pickle + self.__dict__=pickle.load(Input) + def __str__(self,return_deg=True) : + if return_deg : + return "%e, %e" % (self.long.deg, self.colat.deg) + else : + return "%e, %e" % (self.long.rad, self.colat.rad) + +class _ANGLE : + def __init__(self,deg=None,rad=None,Input=None) : + """An angle""" + import pickle + if Input == None : + if (deg == None) and (rad==None) : + self.deg = None + self.rad = None + else : + if (deg != None) : + self.deg = deg + self.rad = deg/180.*np.pi + else : + self.rad = rad + self.deg = rad*180./np.pi + else : + self.__dict__=pickle.load(Input) + def __str__(self) : + return "(%e,%e)" % (self.deg,self.rad) + def __len__(self) : + try : + return len(self.deg) + except : + return 1 + def __str__(self) : + if self.__len__() == 1 : + return "%e, %e" % (self.deg, self.rad) + else : + ll = ["(%e, %e)" % (self.deg[0], self.rad[0])] + ll.append("(%e, %e)" % (self.deg[-1], self.deg[-1])) + return "["+ll[0]+"..."+ll[1]+"]" + def dump(self,output) : + import pickle + pickle.dump(output,self.__dict__) + def load(self,Input) : + import pickle + self.__dict__=pickle.load(Input) + +import numpy as np +class _MAP : + """A map""" + def __init__(self,Nx, Ny,Namex = '', Namey='',dtype=np.float,value=0,Input=None) : + import numpy as np + import pickle + if Input == None : + self.m = np.zeros([Nx, Ny],dtype=dtype)+value + self.Namex = Namex + self.Namey = Namey + else : + self.__dict__=pickle.load(Input) + def __getitem__(self,x,y) : + return self.m[x,y] + def dump(self,output) : + import pickle + pickle.dump(output,self.__dict__) + def load(self,Input) : + import pickle + self.__dict__=pickle.load(Input) + +class GridAxis : + def __init__(self,*karg,**kopt) : + """An axe of a map + axis() + axis(GridAxis) + axis(Struct) + axis(string name) + axis(pyfits hdu) + axis(string name,string unit) + axis(string name,string unit,array values) + axis(string name,string unit,float min, float max, int n) + axis(string name,string unit,float min, float max, float delta) + axis(string name,string unit,list_of_strings) + + Keywords : period + + See grid2d.__VERSION__ for versioning and grid2d.__DESCRIPTION__ for description + """ + from numpy import nan,zeros,array,round,arange + import copy + import pyfits + self.__dict__=self.new() + if len(karg) == 0 : + return + if len(karg) == 1 : + if type(karg[0]) == type({}) : + for k in self.__dict__.keys() : + try : + self.__dict__[k] = copy.deepcopy(karg[0][k]) + except : + print "Error: input structure has not key %s, does it represent an axis?"%k + return + elif type(karg[0]) == type('') : + self.name=karg[0] + return + elif type(karg[0]) == type(pyfits.ImageHDU()) : + self.v=karg[0].data*1 + self.n=len(self.v) + self.min=self.v.min() + self.max=self.v.max() + self.delta=self.v[1]-self.v[0] + self.closed=karg[0].header['closed'] + self.textual=karg[0].header['textual'] + self.dim=karg[0].header['dim'] + self.dimid=karg[0].header['dimid'].strip() + self.unit=karg[0].header['unit'].strip() + self.name=karg[0].header['name'].strip() + try : + self.sampling=karg[0].header['sampling'].strip() + except : + self.sampling='unknown' + if kopt.has_key('period') : + if kopt['period'] == True and type(kopt['period'])==type(True): + self.set_periodic() + elif kopt['period'] != None and kopt['period'] != False and kopt['period'] != nan and kopt['period'] != 0 : + self.set_periodic(period=kopt['period']) + return + else : + self=copy.deepcopy(karg[0]) + return + self.name=karg[0] + self.unit=karg[1] + if len(karg) < 3 : + return + if type(karg[2]) == type(array([])) : + if type(karg[2][0]) != type('') : + self.v = 1.*karg[2] + self.min = self.v.min() + self.max = self.v.max() + self.n = len(self.v) + self.delta = self.v[1]-self.v[0] + else : + self.textual=True + self.text = copy.deepcopy(array(karg[2])) + self.v = arange(0,len(self.text)) + self.n = len(self.v) + self.min = float(self.v.min()) + self.max = float(self.v.max()) + self.delta = 1. + else : + if len(karg) < 4 : + print "error: not enough arguments" + return + self.min=karg[2] + self.max=karg[3] + if type(karg[4]) == type(1) : + self.n=karg[4] + self.delta=(karg[3]-karg[2])/float(karg[4]) + self.v=np.arange(self.min,self.max+self.delta,self.delta) + else : + self.delta=karg[4] + self.n=int(round((karg[3]-karg[2])/float(karg[4]))) + self.v=np.arange(self.min,self.max+self.delta,self.delta) + if kopt.has_key('period') : + if kopt['period'] == True and type(kopt['period'])==type(True): + self.set_periodic() + elif kopt['period'] != None and kopt['period'] != False and kopt['period'] != nan and kopt['period'] != 0 : + self.set_periodic(period=kopt['period']) + def version(self) : + "returns the class version" + return "Formal Revision: 1.0 - 2012 Apr 1" + def new(self) : + from numpy import nan + C = {} + C['name']='' + C['delta']=nan + C['min']=nan + C['max']=nan + C['n']=0 + C['unit']='' + C['v']=None + C['closed']=False + C['textual']=False + C['text']=None + C['dim']=None + C['dimid']='' + C['period_ticks']=-1 + C['sampling']='uniform' + return C + def toImageHDU(self,hduname,comments=[],dim=None,dimid=None,addchecksum=True) : + "convert an axis into an image hdu" + import pyfits + import time + if dim!=None : + _dim=dim + elif self.dim!=None : + _dim=self.dim + else : + _dim=-1 + if dimid!=None and dimid!='' : + _dimid=dimid + elif self.dim!=None and self.dimid!='': + _dimid=self.dimid + else : + _dimid='' + hdu=pyfits.ImageHDU(self.v) + hdu.name=hduname + hdu.header.add_comment('Values of %s axis'%self.name) + hdu.header.add_comment('HDU Created: %s'%time.asctime()) + hdu.header.add_comment(self.version()) + hdu.header.add_comment('NOTES:') + hdu.header.add_comment('+If TEXTUAL is true in place of values indexes are added') + hdu.header.add_comment('+DIM is the dimension of the array to which the axis refer') + hdu.header.add_comment(' The slowest dimension to increase is the most lef') + hdu.header.add_comment(' The slowest dimension to increase is the most lef') + hdu.header.add_comment(' Example: in an array A[i,j,k] DIM=1 is i, DIM=2, is j, DIM=3 is k') + hdu.header.add_comment(' i is slower than j that is slower than k') + hdu.header.add_comment(' Usually in a 2d array A[i,j], i is referred as row, j as column') + try : + if len(comments) > 0 : + if type(comments) == [] : + for line in comments : + if len(line.strip()) > 0 : + hdu.header.add_comment(line.strip()) + else : + for line in comments.split('\n') : + if len(line.strip()) > 0 : + hdu.header.add_comment(line.strip()) + except : + pass + hdu.header.update('dim',_dim,'dimension of array') + hdu.header.update('dimid',_dimid,'row, col or other') + hdu.header.update('name',self.name,'name of axis') + hdu.header.update('unit',self.unit,'unit of axis') + hdu.header.update('min',self.min,'minimum axis') + hdu.header.update('max',self.max,'maximum axis') + hdu.header.update('delta',self.delta,'step of axis (if uniform)') + hdu.header.update('period',self.period,'period in ticks (<=0 no period)') + hdu.header.update('n',self.n,'number of elements of axis') + hdu.header.update('closed',self.closed,'true if closed') + hdu.header.update('textual',self.textual,'true if textual') + hdu.header.update('sampling',self.sampling,'kind of sampling, default uniform') + if addchecksum : + hdu.add_checksum() + return hdu + def right_close(self) : + """ copyes the first row assuming it has the same value of the first, used to give maps with cyclicalBoundaries """ + from numpy import concatenate,ones,arange + import copy + if not self.textual : + self.v = concatenate([self.v,ones(1)*self.v[-1]+self.delta]) + self.n = len(self.v) + self.min = self.v.min() + self.max = self.v.max() + self.closed=True + else : + l=[] + for k in self.text : + l.append(k) + l.append(self.text[0]) + self.text = copy.deepcopy(l) + self.v = arange(0,len(self.text)) + self.n = len(self.v) + self.min = float(self.v.min()) + self.max = float(self.v.max()) + self.delta = 1. + self.closed=True + def set_periodic(self,period=None) : + "makes periodic" + import numpy as np + if period!=None: + self.period_ticks = np.floor(float(period)/self.delta) + else : + self.period_ticks = float(self.n) + def is_periodic(self) : + return self.period_ticks > 0 + def __len__(self) : + return self.n + def __call__(self,*arg) : + if len(arg) == 0 : + return self.__dict__ + elif len(arg) == 1 : + return self.__dict__[arg[0]] + else : + return self.__dict__[arg[0]][arg[1]] + def __getitem__(self,*arg) : + if len(arg) == 0 : + return self.__dict__ + elif len(arg) == 1 : + return self.__dict__[arg[0]] + elif len(arg) == 2 : + return self.__dict__[arg[0]][arg[1]] + elif len(arg) == 3 : + return self.__dict__[arg[0]][arg[1]][arg[2]] + elif len(arg) == 4 : + return self.__dict__[arg[0]][arg[1]][arg[2]][arg[3]] + else : + l=self.__dict__[arg[0]] + for ik in range(1,len(arg)) : + try : + l=l[arg[ik]] + except : + print "Some error extracting element %d of "%ik,arg + return None + def __setitem__(self,*arg) : + import copy + if len(arg) == 1 : + self.__dict__ = copy.deepcopy(arg[0]) + elif len(arg) == 2 : + self.__dict__[arg[1]] = copy.deepcopy(arg[0]) + else : + self.__dict__[arg[1]][arg[2]] = copy.deepcopy(arg[0]) + def keys() : + return self.keys() + +class MapGrid() : + def __init__(self,*karg,**kopt) : #reference_x=None,reference_y=None,mapname=None) + """ + A map gridded + MpG = MapGrid() an empty map + + #deprecated methods + MpG = MapGrid(mapname) a map loaded from a pickle file with name mapname + MpG = MapGrid(nrows,ncols) a map with nrows, ncols + #def __init__(self,mapname,xname,xmin,xmax,nx,xunit,yname,ymin,ymax,ny,yunit,reference_x=None,reference_y=None) + + #preferred methods + MpG = MapGrid(pickle=mapname) a map loaded from a pickle file with name mapname + MpG = MapGrid(Rows=nrows,Cols=ncols) a map with nrows, ncols + MpG = MapGrid(Rows=numpy_array1d,Cols=numpy_array1d) a map with rows and cols listed as numpy 1d arrays + MpG = MapGrid(Rows=GridAxisRows,Cols=GridAxisCols) a map with rows and cols specified by GridAxis objects + MpG = MapGrid(model=numpy_array2d) a map with format specified by a 2D numpy array taken as model + + keyword mapname sets a name to a map + """ + import numpy as np + import pickle + import copy + _Verbose = kopt.has_key('Verbose')==True if kopt.has_key('Verbose') else False + self.clean(__verbose__=_Verbose) + #print len(karg) + if len(karg) == 0 : + kkopt=kopt.copy() + if len(kopt) == 0 : + return + if kopt.has_key('mapname') : + self.mapname=kopt['mapname'] + if kopt.has_key('pickle') : + self.getFromPickle(kopt['pickle']) + return + if kopt.has_key('fits') : + self.getFromFits(kopt['fits']) + return + if kopt.has_key('model') : + self.createBaseGrid_from_model(kopt['model'],**kopt) + return + if kopt.has_key('Rows') and kopt.has_key('Cols'): + if type(kopt['Rows'])==type(0) and type(kopt['Cols'])==type(0) : + self.createBaseGrid_from_nrowsncols(*karg,**kopt) + return + elif type(kopt['Rows'])==type(np.array([])) and type(kopt['Cols'])==type(np.array([])) : + kkopt['Cols']=GridAxis('x','',kopt['Cols']) + kkopt['Rows']=GridAxis('y','',kopt['Rows']) + self.createBaseGrid_from_gridaxis(*karg,**kkopt) + return + elif kopt['Rows'].__class__==GridAxis().__class__ and kopt['Cols'].__class__==GridAxis().__class__ : + self.createBaseGrid_from_gridaxis(*karg,**kopt) + return + elif type(kopt['Rows'])==type({}) and type(kopt['Cols'])==type({}) : + kkopt=kopt.copy() + kkopt['Rows'] = GridAxis(kopt['Rows']) + kkopt['Cols'] = GridAxis(kopt['Cols']) + self.createBaseGrid_from_gridaxis(*karg,**kkopt) + return + else : + if _Verbose : print "Unknown signature, empy object created" + return + return + if len(karg)==1 : + kkopt = kopt.copy() + if type(karg[0]) == type('') : + kkopt['pickle']=karg[0] + self.getFromPickle(self,*karg,**kkopt) + return + elif type(karg[0]) == type(np.array()): + kkopt['model']=karg[0] + self.createBaseGrid_from_model(karg[0],**kkopt) + return + else : + if _Verbose : print "Unknown signature, empy object created" + return + if len(karg)==2 : + kkopt = kopt.copy() + if type(karg[0]) == type(0) and type(karg[1]) == type(0) : + kkopt['Rows']=karg[1] + kkopt['Cols']=karg[0] + self.createBaseGrid_from_nrowsncols(*karg,**kkopt) + elif karg[0].__class__==GridAxis().__class__ and karg[1].__class__==GridAxis().__class__ : + kkopt['Rows']=karg[1] + kkopt['Cols']=karg[0] + self.createBaseGrid_from_gridaxis(*karg,**kkopt) + elif type(karg[0]) == type(0) and type(karg[1]) == type(0) : + kkopt['Rows']=karg[1] + kkopt['Cols']=karg[0] + return + + def isVerbose(self) : return self.__verbose__ + + def newaxis(self) : + return GridAxis().__dict__ + + def clean(self,shape=None,__verbose__=False) : + from collections import OrderedDict + from numpy import nan,zeros + self.info=OrderedDict() + self.mapname = '' + # sets the phi along the x axis of the grid i.e. the columns + self.C = GridAxis().__dict__ + # sets the theta along the y axis of the grid i.e. the rows + self.R = GridAxis().__dict__ + # sets the remaining + self.naxis=2 if shape == None else len(list(shape)) + self.shape=[0,0] if shape == None else list(shape) + self.center=zeros(2) if shape == None else np.array([int(shape[0]/2),int(shape[1]/2)]) + self.centerRow=-1 if shape == None else int(shape[0]/2) + self.centerCol=-1 if shape == None else int(shape[1]/2) + self.pickle_name = '' + self.fits_name = '' + self.M=OrderedDict() + self.unit=OrderedDict() + self.f=OrderedDict() + self.ncols=self.shape[1] + self.nrows=self.shape[0] + self.map_info=OrderedDict() + self.__verbose__=__verbose__ + + def createBaseGrid_empty(self,*karg,**kopt) : + """creates a base grid empty after a clean(shape=shape)""" + # + if kopt.has_key('mapname') : self.mapname=kopt['mapname'] + # + self.C = GridAxis().__dict__ + self.R = GridAxis().__dict__ + xname = 'x' if not kopt.has_key('xname') else kopt['xname'] + yname = 'y' if not kopt.has_key('yname') else kopt['yname'] + xunit = '' if not kopt.has_key('xunit') else kopt['xunit'] + yunit = '' if not kopt.has_key('yunit') else kopt['yunit'] + self.set_col_scale(xname,xunit,np.arange(self.ncols)) + self.set_row_scale(yname,yunit,np.arange(self.nrows)) + # + self.map_info['_col_index']={'comment':'index of cols','private':True} + self.map_info['_col_values']={'comment':'values of cols','private':True} + self.M['_col_index']=np.zeros([self.R['n'],self.C['n']],dtype='int') + self.M['_col_values']=np.zeros([self.R['n'],self.C['n']],dtype='float') + for ic in range(self.C['n']) : + self.M['_col_index'][:,ic] = ic + self.M['_col_values'][:,ic] = self.C['v'][ic] + # + self.map_info['_row_index']={'comment':'index of rows','private':True} + self.map_info['_row_values']={'comment':'values of rows','private':True} + self.M['_row_index']=np.zeros([self.R['n'],self.C['n']],dtype='int') + self.M['_row_values']=np.zeros([self.R['n'],self.C['n']],dtype='float') + for ir in range(self.R['n']) : + self.M['_row_index'][ir] = ir + self.M['_row_values'][ir] = self.R['v'][ir] + + def createBaseGrid_from_model(self,*karg,**kopt) : + """creates a base grid from a model map or a dictionary of model maps""" + from collections import OrderedDict + if kopt.has_key('verbose') : + if kopt['verbose'] : + print "createBaseGrid from model",karg,kopt + if type(kopt['model']) == type({}) or type(kopt['model']) == type(OrderedDict()) : + lk=kopt['model'].keys() + MapGrid.clean(self,shape=kopt['model'][lk[0]].shape) + self.createBaseGrid_empty(*karg,**kopt) + for k in lk : + self.newmap(k,value=kopt['model'][k].copy()) + self.map_info[k]={'comment':'map '+k,'private':False} + return + MapGrid.clean(self,shape=kopt['model'].shape) + self.createBaseGrid_empty(*karg,**kopt) + self.newmap('model',value=kopt['model'].copy()) + self.map_info['model']={'comment':'model map','private':False} + + def createBaseGrid_from_nrowsncols(self,*karg,**kopt) : + """creates a base grid""" + if kopt.has_key('verbose') : + if kopt['verbose'] : + print "createBaseGrid ",karg,kopt + MapGrid.clean(self,shape=[kopt['Rows'],kopt['Cols']]) + self.createBaseGrid_empty(*karg,**kopt) + + def createBaseGrid_from_gridaxis(self,*karg,**kopt) : + """creates a base grid""" + if kopt.has_key('verbose') : + if kopt['verbose'] : + print "createBaseGrid ",karg,kopt + MapGrid.clean(self) + # + if kopt.has_key('mapname') : self.mapname=kopt['mapname'] + # + self.C = kopt['Cols'].__dict__ + self.ncols=len(kopt['Cols']) + # + self.R = kopt['Rows'].__dict__ + self.nrows=len(kopt['Rows']) + # + self.map_info['_col_index']={'comment':'index of cols','private':True} + self.map_info['_col_values']={'comment':'values of cols','private':True} + self.M['_col_index']=np.zeros([self.R['n'],self.C['n']],dtype='int') + self.M['_col_values']=np.zeros([self.R['n'],self.C['n']],dtype='float') + for ic in range(self.C['n']) : + self.M['_col_index'][:,ic] = ic + self.M['_col_values'][:,ic] = self.C['v'][ic] + # + self.map_info['_row_index']={'comment':'index of rows','private':True} + self.map_info['_row_values']={'comment':'values of rows','private':True} + self.M['_row_index']=np.zeros([self.R['n'],self.C['n']],dtype='int') + self.M['_row_values']=np.zeros([self.R['n'],self.C['n']],dtype='float') + for ir in range(self.R['n']) : + self.M['_row_index'][ir] = ir + self.M['_row_values'][ir] = self.R['v'][ir] + + def createBaseGrid(self,*karg,**kopt) : + """creates a base grid""" + kkopt=kopt.copy() + kkopt['Cols']=karg[1] + kkopt['Rows']=karg[0] + self.createBaseGrid_from_nrowsncols(*karg,**kkopt) + + def getFromPickle(self,*karg,**kopt) : + """get from pickle file""" + if type(karg[0]) == type('') : + try : + self=pickle.load(open(karg[0],'r')) + self.picke_name=karg[0] + except : + raise Error('Pickle %s not found or unreadable'%karg[0]) + return + + def pickle(self,fname) : + import pickle + f=open(fname,'w') + pickle.dump(self.__dict__,f) + f.close() + + def load(self,fname) : + import pickle + self.__dict__= pickle.load(open(fname,'r')) + + def slice(self,row_min=0,row_max=-1,col_min=0,col_max=-1) : + """extract a subgrid in the range [row_min:row_max,col_min:col_max] + row_max=-1 is the last row + col_max=-1 is the last col + the object has no longer closed cols and rows event if the source is closed + if the number of rows is even the centerRow is int(floor(nrows/2))-1 and center[0] is v[centerRow] + if it is odd the centerRow is int(floor(nrows/2)) and center[0] is v[centerRow] + the same for cols and center[1] + """ + import copy + import numpy as np + # copies the object but the matrices or vectors + new = self.copy(skipFields=['R','C','M']) + # resizes R + new.R = copy.deepcopy(self.R) + new.R['v']=self.R['v'][row_min:row_max] + new.R['n']=len(new.R['v']) + new.R['min']=new.R['v'].min() + new.R['max']=new.R['v'].max() + new.R['closed']=False + # resizes C + new.C = copy.deepcopy(self.C) + new.C['v']=self.C['v'][col_min:col_max] + new.C['n']=len(new.C['v']) + new.C['min']=new.C['v'].min() + new.C['max']=new.C['v'].max() + new.C['closed']=False + # resizes M + for k in self.M.keys() : + k1 = k if k!='_col_index' and k!='_row_index' else '_original'+k + new.M[k1]=self.M[k][row_min:row_max,col_min:col_max] + new.M['_col_index'] = new.M['_original_col_index']-col_min + new.M['_row_index'] = new.M['_original_row_index']-row_min + new.shape=[new.R['n'],new.C['n']] + new.centerRow=int(np.floor(new.R['n']/2))-1*(np.mod(new.R['n'],2) == 0) + new.centerCol=int(np.floor(new.C['n']/2))-1*(np.mod(new.C['n'],2) == 0) + new.center[0]=new.R['v'][new.centerRow] + new.center[1]=new.C['v'][new.centerCol] + return new + def slice_row(self,irow_list) : + """creates a submap whose rows are listes in irow_list + """ + import copy + import numpy as np + # copies the object but the matrices or vectors + new = self.copy() + # resizes R + new.R = copy.deepcopy(self.R) + new.R['v']=self.R['v'][irow_list] + new.R['n']=len(new.R['v']) + new.R['min']=new.R['v'].min() + new.R['max']=new.R['v'].max() + new.R['closed']=False + # resizes M + for k in self.M.keys() : + k1 = k if k!='_row_index' else '_original'+k + new.M[k1]=self.M[k][irow_list] + new.M['_row_index'] = new.zeros(dtype='int') + for k in range(new.R['n']) : new.M['_row_index'][k]=k + new.shape=new.SHAPE() + new.centerRow=int(np.floor(new.R['n']/2))-1*(np.mod(new.R['n'],2) == 0) + new.centerCol=int(np.floor(new.C['n']/2))-1*(np.mod(new.C['n'],2) == 0) + new.center[0]=new.R['v'][new.centerRow] + new.center[1]=new.C['v'][new.centerCol] + return new + def submap(self,xmin,xmax,ymin,ymax) : + """extracts a submap with xmin <= col.v <= xmax, ymin <= row.v <= ymax + values are interpolated if needed + """ + import numpy as np + def local_interp(x,x0,x1,y0,y1) : return (y1-y0)*(x-x0)/(x1-x0)+y0 + def allowed_name(name) : + return name != '_col_index' and name != '_row_index' and name != '_original_col_index' and name != '_original_row_index' + # find the columns list + # elements selected are those for which xmin <= col.v <= xmax + # if xmin is midway the points in the list of values includes one point at left + # if xmax is midway the points in the list of values includes one point at right + flag = np.ones(self.C['n']) + if xmin != None : flag *= xmin <= self.C['v'] + if xmax != None : flag *= self.C['v'] <= xmax + idxC=np.where(flag)[0] + if len(idxC) == 0 : + #idxC=np.array([np.where(xmin <= self.C['v'])[0][0]]) + raise Error("Error, extremes outside boundary, or both within an interval") + return None + xminXT=False ; xmaxXT=False + if xmin < self.C['v'][idxC[0]] and idxC[0] > 0 : + idxC=np.concatenate((np.array([idxC[0]-1]),idxC)) + xminXT=True + if self.C['v'][idxC[-1]] < xmax and idxC[-1] < self.C['n']-1 : + idxC=np.concatenate((idxC,np.array([idxC[-1]+1]))) + xmaxXT=True + # find the rows list + # elements selected are those for which ymin <= row.v <= ymax + # if ymin is midway the points in the list of values includes one point at left + # if ymax is midway the points in the list of values includes one point at right + flag = np.ones(self.R['n']) + if ymin != None : flag *= ymin <= self.R['v'] + if ymax != None : flag *= self.R['v'] <= ymax + idxR=np.where(flag)[0] + if len(idxR) == 0 : + #idxR=np.array([np.where(ymin <= self.R['v'])[0][0]]) + raise Error("Error, extremes outside boundary, or both within an interval") + return None + yminXT=False ; ymaxXT=False + if ymin < self.R['v'][idxR[0]] and idxR[0] > 0 : + idxR=np.concatenate((np.array([idxR[0]-1]),idxR)) + yminXT=True + if self.R['v'][idxR[-1]] < ymax and idxR[-1] < self.R['n']-1 : + idxR=np.concatenate((idxR,np.array([idxR[-1]+1]))) + ymaxXT=True + # extracts sliced map + new = self.slice(row_min=idxR[0],row_max=idxR[-1]+1,col_min=idxC[0],col_max=idxC[-1]+1) + # if needed interpolates values at midway + if xminXT : + for k in self.M.keys() : + if allowed_name(k) : + new.M[k][:,0]=local_interp(xmin,new.C['v'][0],new.C['v'][1],new.M[k][:,0],new.M[k][:,1]) + new.C['v'][0] = xmin + if xmaxXT : + for k in self.M.keys() : + if allowed_name(k) : + new.M[k][:,-1]=local_interp(xmax,new.C['v'][-2],new.C['v'][-1],new.M[k][:,-2],new.M[k][:,-1]) + new.C['v'][-1] = xmax + if xminXT or xmaxXT : new.C['sampling']=['not-uniform'] + if yminXT : + for k in self.M.keys() : + if allowed_name(k) : + new.M[k][0,:]=local_interp(ymin,new.R['v'][0],new.R['v'][1],new.M[k][0,:],new.M[k][1,:]) + new.R['v'][0] = ymin + if ymaxXT : + for k in self.M.keys() : + if allowed_name(k) : + new.M[k][-1,:]=local_interp(ymax,new.R['v'][-2],new.R['v'][-1],new.M[k][-2,:],new.M[k][-1,:]) + new.R['v'][-1] = ymax + if yminXT or ymaxXT : new.R['sampling']=['not-uniform'] + return new + def __len__(self) : + return self.shape[0]*self.shape[1] + def __getitem__(self,*args) : + if len(args) == 1 : + try : + return self.M[args[0]] + except : + raise Error("invalid argument") + elif len(args) == 2 : + try : + return self.M[args[0]][args[1]] + except : + raise Error("invalid argument") + elif len(args) == 3 : + try : + return self.M[args[0]][args[1]][args[2]] + except : + raise Error("invalid argument") + elif len(args) == 4 : + try : + return self.M[args[0]][args[1]][args[2]] + except : + raise Error("invalid argument") + else : + if len(l) > self.naxis : + raise Error("invalid argument") + l=self.__dict__[args[0]] + for ik in range(1,len(args)) : + try : + l=l[args[ik]] + except : + raise Error(("Some error extracting element %d of "%ik)+str(args)) + def __setitem__(self,*args) : + import copy + if len(args) == 2 : + try : + self.M[args[0]]=copy.deepcopy(args[1]) + except : + raise Error("invalid argument") + elif len(args) == 3 : + try : + self.M[args[0]][args[1]]=copy.deepcopy(args[2]) + except : + raise Error("invalid argument") + elif len(args) == 4 : + try : + self.M[args[0]][args[1]][args[2]]=copy.deepcopy(args[3]) + except : + raise Error("invalid argument") + else : + raise Error("invalid argument") + def refresh(self) : + if self.naxis == 2 : + self.shape=(self.R['n'],self.C['n']) + elif self.naxis == 3 : + self.shape=(self.R['n'],self.C['n'],self.Z['n']) + else : + raise Error("Inconsistent naxis") + def idx2colrow(self,idx) : + "given a idx (a pixel number) returns corresponding col,row " + import numpy as np + return np.mod(idx,self.shape[1]),idx/self.shape[1] + def colrow2idx(self,col,row) : + "given col,row returns corresponding a idx (a pixel number) " + import numpy as np + return col+row*self.shape[1] + def xy2colrow(self,x,y) : + """xy to col row""" + return (x-self.C['min'])/self.C['delta'],(y-self.R['min'])/self.R['delta'] + def colrow2xy(self,col,row) : + """xy to col row""" + return self.C['min']+col*self.C['delta'],self.R['min']+row*self.R['delta'] + def SHAPE(self) : + return [self.R['n'],self.C['n']] + def zeros(self,dtype='float',maxdim=None) : + from numpy import zeros + ii=self.naxis if (self.naxis <= maxdim) or (maxdim<=0) or maxdim==None else maxdim + return zeros(list(self.SHAPE()),dtype=dtype) + #return zeros(list(self.shape)[0:(maxdim+1)],dtype=dtype) + def newmap(self,name,unit='',value=None,dtype='float',comment='') : + from numpy import nan,zeros + self.M[name] = self.zeros(dtype=dtype) + self.unit[name] = unit + if value == None : + if type(dtype) == type('') : + if dtype.strip() !='int' : + self.M[name] += nan + else : + if dtype != type(1) : + self.M[name] += nan + else : + self.M[name] += value + def clean_matrices(self): + self.M={} + self.newmap('_row_values') + self.newmap('_row_index',dtype='int') + self.newmap('_col_values') + self.newmap('_col_index',dtype='int') + def set_row_periodic(self,period=None) : + "makes Row periodic" + import numpy as np + self.R['period_ticks']=False + if period!=None: + self.R['period_ticks'] = np.floor(float(period)/self.R['delta']) + else : + self.R['period_ticks'] = float(self.R['n']) + def set_row_scale(self,*karg,**kopt) : + """ set_row_scale(string name) + set_row_scale(string name,string unit) + set_row_scale(string name,string unit,array values) + set_row_scale(string name,string unit,float min, float max, int n) + set_row_scale(string name,string unit,float min, float max, float delta) + keywords: + period = period of the row variable, default FALSE + """ + from numpy import nan,zeros,array,round + self.R['period_ticks']=False + self.R['closed']=False + self.R['name']=karg[0] + if len(karg) < 2 : + return + self.R['unit']=karg[1] + if len(karg) < 3 : + return + self.shape[0]=0 + if type(karg[2]) == type(array([])) : + self.R['v'] = 1.*karg[2] + self.R['min'] = self.R['v'].min() + self.R['max'] = self.R['v'].max() + self.R['n'] = len(self.R['v']) + self.R['delta'] = self.R['v'][1]-self.R['v'][0] + else : + if len(karg) < 4 : + raise Error("error: not enough arguments") + return + self.R['min']=karg[2] + self.R['max']=karg[3] + if type(karg[4]) == type(1) : + self.R['n']=karg[4] + self.R['delta']=(karg[3]-karg[2])/float(karg[4]) + else : + self.R['delta']=karg[4] + self.R['n']=int(round((karg[3]-karg[2])/float(karg[4]))) + self.shape[0]=self.R['n']*1 + if self.shape[0]*self.shape[1] > 0: + self.clean_matrices() + if kopt.has_key('periodic') : + periodic = kopt['periodic'] + if periodic != None and period != False: + if periodic == True : + self.R['period_ticks']=float(self.R['n']) + else : + self.R['period_ticks']=periodic/float(self.R['step']) + else : + self.R['period_ticks']=False + def set_col_periodic(self,period=None) : + "makes Col periodic" + import numpy as np + self.C['period_ticks']=False + if period!=None: + self.C['period_ticks'] = np.floor(float(period)/self.C['delta']) + else : + self.C['period_ticks'] = float(self.C['n']) + def set_col_scale(self,*karg,**kopt) : + """ set_col_scale(string name) + set_col_scale(string name,string unit) + set_col_scale(string name,string unit,array values) + set_col_scale(string name,string unit,float min, float max, int n) + set_col_scale(string name,string unit,float min, float max, float delta) + """ + from numpy import nan,zeros,array,round + self.C['period_ticks']=-1 + self.C['closed']=False + self.C['name']=karg[0] + if len(karg) < 2 : + return + self.C['unit']=karg[1] + if len(karg) < 3 : + return + self.shape[1]=0 + if type(karg[2]) == type(array([])) : + self.C['v'] = 1.*karg[2] + self.C['min'] = self.C['v'].min() + self.C['max'] = self.C['v'].max() + self.C['n'] = len(self.C['v']) + self.C['delta'] = self.C['v'][1]-self.C['v'][0] + else : + if len(karg) < 4 : + raise Error("error: not enough arguments") + return + self.C['min']=karg[2] + self.C['max']=karg[3] + if type(karg[5]) == type(1) : + self.C['n']=karg[4] + self.C['delta']=(karg[3]-karg[2])/float(karg[4]) + else : + self.C['delta']=karg[4] + self.C['n']=int(round((karg[3]-karg[2])/float(karg[4]))) + self.shape[1]=self.C['n']*1 + if self.shape[0]*self.shape[1] > 0: + self.clean_matrices() + if kopt.has_key('periodic') : + periodic = kopt['periodic'] + if periodic != None and period != False: + if periodic == True : + self.C['period_ticks']=float(self.C['n']) + else : + self.C['period_ticks']=periodic/float(self.C['step']) + else : + self.C['period_ticks']=False + def right_close_row(self,period=False) : + """ copyes the first row assuming it has the same value of the first, used to give maps with cyclicalBoundaries """ + from numpy import concatenate,ones + self.R['v'] = concatenate([self.R['v'],ones(1)*self.R['v'][-1]+self.R['delta']]) + self.R['n'] = len(self.R['v']) + self.R['min'] = self.R['v'].min() + self.R['max'] = self.R['v'].max() + self.R['closed']=True + if period != None and period != False: + if period == True : + self.R['period_ticks']=float(self.R['n']) + else : + self.R['period_ticks']=period/float(self.R['step']) + else : + self.R['period_ticks']=False + self.shape[0]=len(self.R['v']) + if self.M!=None and self.M!={}: + for k in self.M.keys() : + self.M[k]=concatenate([self.M[k],self.M[k][0:1]]) + def right_close_col(self,period=False,right_col_value=None) : + """ copyes the first row assuming it has the same value of the first, used to give maps with cyclicalBoundaries """ + from numpy import concatenate,ones,array,zeros + import copy + self.C['v'] = concatenate([self.C['v'],ones(1)*self.C['v'][-1]+self.C['delta']]) + if right_col_value != None : + try : + self.C['v'][-1]=float(right_col_value) + except : + pass + self.C['n'] = len(self.C['v']) + self.C['min'] = self.C['v'].min() + self.C['max'] = self.C['v'].max() + self.C['closed']=True + if period != None and period != False: + if period == True : + self.C['period_ticks']=float(self.C['n']) + else : + self.C['period_ticks']=period/float(self.C['step']) + else : + self.C['period_ticks']=False + self.shape[1]=len(self.C['v']) + if self.M!=None and self.M!={} : + for k in self.M.keys() : + M=copy.deepcopy(self.M[k]) + self.M[k]=zeros(M.shape+array([0,1])) + if k=='_row_values' : + for r in range(self.R['n']) : + self.M[k][r]=concatenate([M[r,:],M[r,0]*ones(1)]) + elif k=='_col_values' : + for r in range(self.R['n']) : + self.M[k][r]=concatenate([M[r,:],M[r,-1]+self.C['delta']*ones(1)]) + if right_col_value != None : + try : + self.M[k][r][-1]=float(right_col_value) + except : + pass + elif k=='_row_index' : + for r in range(self.R['n']) : + self.M[k][r]=concatenate([M[r,:],M[r,0]*ones(1)]) + elif k=='_col_index' : + for r in range(self.R['n']) : + self.M[k][r]=concatenate([M[r,:],M[r,-1]+ones(1)]) + else : + for r in range(self.R['n']) : + self.M[k][r]=concatenate([M[r,:],M[r,0:1]]) + def keys(self,private=False,all=False) : + p = [] + for k in self.M.keys() : + if k[0]!='_' : + if not private : + p.append(k) + else : + if private or all : + p.append(k) + return p + def has_key(self,name) : + from numpy import array + return self.M.has_key(name) + def transpose(self) : + import copy + from numpy import transpose + if self.naxis != 2 : + raise Error("transpose is defined just for naxis=2") + M = MapGrid() + M.info = copy.deepcopy(self.info) + M.unit = copy.deepcopy(self.unit) + M.R = copy.deepcopy(self.C) + M.C = copy.deepcopy(self.R) + M.shape=[M.R['n'],M.C['n']] + for k in self.M.keys() : + M.M[k]=transpose(self.M[k]) + return M + def create_interpolation_function(self,*args,**kargs) : + """Creates the interpolation (2d) functions""" + from scipy import interpolate + from numpy import array + if self.naxis != 2 : + raise Error("create_interpolation_function is defined just for naxis=2") + try : + kind=kargs['kind'] + except : + kind='linear' + if (array(['linear','cubic','quintic'])==kind).sum() == 0 : + print "Kind %s not allowed"%kind + return None + if self.f != type({}) : + self.f={} + if len(args) == 0 : + ln=self.keys() + else : + ln = args + for k in ln : + self.f[k]=interpolate.interp2d(self.R['v'],self.C['v'],self.M[k],kind=kind) + def interpolate(self,name,x_col,y_row) : + from numpy import array + if self.naxis != 2 : + raise Error("interpolate is defined just for naxis=2") + if self.f != type({}) : + self.f={} + if not self.f.has_key(name) : + try : + print 'creating', + self.create_interpolation_function(name) + except : + print "Matrix %s not found in creating interpolation function"%name + else : + try : + return self.f[k](y_row,x_col) + except : + raise Error("Matrix %s not found or out of bounds"%name) + return None + def copy(self,skipFields=None) : + import copy + import numpy as np + if skipFields == None or skipFields == '' or skipFields == [] : return copy.deepcopy(self) + _skipFields=[] + for k in [skipFields] if type(skipFields) == type('') else skipFields : + if k.strip() != '' : _skipFields.append(k.strip()) + _skipFields = np.array(['']) if len(_skipFields) == 0 else np.array(_skipFields) + new=MapGrid() + for k in self.__dict__.keys() : + if (_skipFields == k).sum() == 0 : + new.__dict__[k]=copy.deepcopy(self.__dict__[k]) + return new + def rowClip(self,row,offset) : + """applies a clipping to row number, return clippedRow,flagBad + flagBad = -10 : under flow + flagBad = -1 : overflow """ + if self.R['period_ticks']>0 : + return np.mod(row+offset,self.R['period_ticks']),np.zeros(len(row)) + else : + row1=row+offset + bad = -10*(row1<0)-(self.R['n']-1<row1) + return row1*(bad==0),bad + def colClip(self,col,offset) : + """applies a clipping to col number, return clippedRow,flagBad + flagBad = -10 : under flow + flagBad = -1 : overflow""" + if self.C['period_ticks']>0 : + return np.mod(col+offset,self.C['period_ticks']),np.zeros(len(col)) + else : + col1=col+offset + bad = -10*(col1<0)-(self.C['n']-1<col1) + return col1*(bad==0),bad + def XY2RowCol(self,x_col,y_row) : + import numpy as np + return (y_row-self.R['min'])/self.R['delta'],(x_col-self.C['min'])/self.C['delta'] + def RowCol2XY(self,row,col) : + return col*self.C['delta']+self.C['min'],row*self.R['delta']+self.R['min'] + def downgrade(self,FactorR,FactorC) : + """reduces resolution of a given factor + values outside the resampled points are removed + """ + if self.naxis != 2 : raise Error("downgrade is defined just for naxis=2") + import copy + import numpy as np + new=self.copy() + new.clean() + try : + new.info=copy.deepcopy(self.info) + except : + pass + try : + new.Info=copy.deepcopy(self.Info) + except : + pass + for k in ['unit','name','dim','dimid','textual'] : + new.C[k]=copy.deepcopy(self.C[k]) + new.R[k]=copy.deepcopy(self.R[k]) + idxC=np.where(np.mod(np.arange(self.C['n'],dtype='int'),int(FactorC))==0)[0] + new.C['v']=self.C['v'][idxC] + new.C['n']=len(idxC) + new.C['min']=new.C['v'].min() + new.C['max']=new.C['v'].max() + new.C['delta']=new.C['v'][0:2].ptp() + idxR=np.where(np.mod(np.arange(self.R['n'],dtype='int'),int(FactorR))==0)[0] + new.R['v']=self.R['v'][idxR] + new.R['n']=len(idxR) + new.R['min']=new.R['v'].min() + new.R['max']=new.R['v'].max() + new.R['delta']=new.R['v'][0:2].ptp() + ROWS=np.array(copy.deepcopy(self.M['_row_index']),dtype='int') + COLS=np.array(copy.deepcopy(self.M['_col_index']),dtype='int') + shape2=copy.deepcopy(ROWS.shape) + shape1=shape2[0]*shape2[1] + ROWS.shape=shape1 + COLS.shape=shape1 + flagROWS=np.mod(ROWS,int(FactorR))==0 + flagCOLS=np.mod(COLS,int(FactorC))==0 + idxRC=np.where(flagROWS*flagCOLS)[0] + for k in self.M.keys() : + aa=copy.deepcopy(self.M[k]) + aa.shape=shape1 + if k!='_row_index' and k!='_col_index' : + new.M[k]=aa[idxRC] + else : + new.M[k]=np.array(aa[idxRC]/FactorR,dtype='int') + for k in new.M.keys() : new.M[k].shape=(new.R['n'],new.C['n']) + new.shape=(new.R['n'],new.C['n']) + new.center=np.zeros(2) + new.centerRow=self.centerRow/FactorR + new.centerCol=self.centerCol/FactorC + new.pickle_name = '' + new.unit=copy.deepcopy(self.unit) + self.f={} + return new + def bilinearXY(self,component,x_col,y_row,returnVal=None,returnDelta=False) : + """ + interpolates a 2d map by using bilinear interpolation + clips to zero all the components outside the limits of the map + unless /returNaN is set in which case returns NaN + periodicColumns = True column indexes are considered periodic + periodicRows = True row indexes are considered periodic + if returnDelta=True returns result,deltaX,deltaY (default False) + """ + if self.naxis != 2 : raise Error("bilinearXY is defined just for naxis=2") + from numpy import mod,nan,zeros,array,round,arange,floor,where + if returnVal == None : + retVal = nan + else : + retVal = returnVal*1 + row,col = self.XY2RowCol(x_col,y_row) + # + drow=mod(row,1) + dcol=mod(col,1) + row00,badR00=self.rowClip(array(floor(row),dtype='int'),0) + row01 = row00 + row10,badR10 = self.rowClip(row00,1) + row11 = row10 + # + col00,badC00=self.colClip(array(floor(col),dtype='int'),0) + col00=array(col00,dtype='int') + col10=col00 + col01,badC01=self.colClip(col00,1) + col01=array(col01,dtype='int') + col11=col01 + # + if type(component)==type('') : + V00 = self.M[component][row00,col00] + V01 = self.M[component][row01,col01] + V10 = self.M[component][row10,col10] + V11 = self.M[component][row11,col11] + else : + V00 = component[row00,col00] + V01 = component[row01,col01] + V10 = component[row10,col10] + V11 = component[row11,col11] + A=V00+dcol*(V01-V00)*(badC01==0) + B=V10+dcol*(V11-V10)*(badC01==0) + result=(badR10==0)*drow*(B-A)+A + result[where(badR00!=0)[0]]=retVal + result[where(badC00!=0)[0]]=retVal + result[where((badR10!=0)*(drow > 0))[0]]=retVal + result[where((badC01!=0)*(dcol > 0))[0]]=retVal + if returnDelta : + return result,dcol,drow + return result + def imshow(self,component,**karg) : + from matplotlib import pyplot as plt + from scipy import interp + from matplotlib import cm + # + kkarg=karg.copy() + if not kkarg.has_key('bar') : kkarg['bar']=False + if not kkarg.has_key('cmap') : kkarg['cmap']='hsv' + if not kkarg.has_key('dbi') : kkarg['dbi']=False + if not kkarg.has_key('log') : kkarg['log']=False + if not kkarg.has_key('slices') : kkarg['slices']=None + if not kkarg.has_key('xticks') : kkarg['xticks']=True + if not kkarg.has_key('yticks') : kkarg['yticks']=True + if not kkarg.has_key('maptitle') : kkarg['maptitle']=None + if not kkarg.has_key('vmin') : kkarg['vmin']=None + if not kkarg.has_key('vmax') : kkarg['vmax']=None + if not kkarg.has_key('interpolation') : kkarg['interpolation']=None + if not kkarg.has_key('newfig') : kkarg['newfig']=True + if not kkarg.has_key('DrawOrShow') : kkarg['DrawOrShow']='show' + # + DrawOrShow=kkarg.pop('DrawOrShow') + # + cmap=kkarg.pop('cmap') + if type(cmap) == type("") : + try : + _cm=cm.__dict__[cmap] + except : + if self.isVerbose() : + print "required cmap ",cmap," no found, replaced with 'hsv'" + print "allowed values " + print cm.__dict__.keys() + else : + _cm=cmap + # + xticks=kkarg.pop('xticks') + if xticks.__class__!=[].__class__ and xticks.__class__!=().__class__ and xticks.__class__!=np.array([]).__class__ : + _xticks=xticks!= None and xticks!= False + else : + _xticks=True + yticks=kkarg.pop('yticks') + if yticks.__class__!=[].__class__ and yticks.__class__!=().__class__ and yticks.__class__!=np.array([]).__class__ : + _yticks = yticks!= None and yticks!= False + else : + _yticks=True + # + newfig=kkarg.pop('newfig') + maptitle=kkarg.pop('maptitle') + slices=kkarg.pop('slices') + dbi=kkarg.pop('dbi') + log=kkarg.pop('log') + bar=kkarg.pop('bar') + # + if newfig : plt.figure() + # + kkarg['cmap']=_cm + kkarg['origin']='lower' + if type(component) == type('') : + if self.naxis != 2 and slicep==None : raise Error("imshow() needs to define the slice") + if self.isVerbose() : + print 'component is a string ', + print component + title=component+'' + if type(maptitle) == type('') : title = maptitle+title + if self.isVerbose() : print title + if self.naxis == 2 : + mm = self[component] + elif self.naxis == 3 : + mm = self[component][:,:,slices] + else : + raise Error("imshow() for naxis not 2 or 3") + if dbi : + plt.imshow(10*np.log10(mm),**kkarg) + title+=', dbi' + elif log : + plt.imshow(np.log10(mm),**kkarg) + title+=', log' + else : + plt.imshow(mm,**kkarg) + else : + if self.isVerbose() : print 'component is an array' + title='' + if type(maptitle) == type('') : title = maptitle + if self.isVerbose() : print title + if dbi : + plt.imshow(10*np.log10(component),**kkarg) + title+=', dbi' + elif log : + plt.imshow(np.log10(component),**kkarg) + title+=', log' + else : + plt.imshow(component,**kkarg) + if bar!=False and bar !='' and bar != None: + if bar == True or bar == 'v' or bar == 'V' : + plt.colorbar(orientation='vertical') + else : + plt.colorbar(orientation='horizontal') + a=self.C['name'].strip() + if _xticks : + if self.C['unit'].strip() != '' : + a+=' ['+self.C['unit'].strip()+']' + else : + a+=' [pixel]' + plt.xlabel(a) + a=self.R['name'].strip() + if _yticks : + if self.R['unit'].strip() != '' : + a+=' ['+self.R['unit'].strip()+']' + else : + a+=' [pixel]' + plt.ylabel(a) + if xticks.__class__!=[].__class__ and xticks.__class__!=().__class__ and xticks.__class__!=np.array([]).__class__ : + if type(xticks)==type(0) or type(xticks)==type(0.): + xt=np.arange(0,self.C['n'],self.C['n']/int(xticks)) + else : + xt=np.arange(0,self.C['n'],self.C['n']/4) + else : + xt=np.array(xticks) + xt1=np.arange(self.C['n']) + if _xticks: + yt1=self.M['_col_values'][0] + else : + yt1=self.M['_col_index'][0] + plt.xticks(xt,interp(xt,xt1,yt1)) + if yticks.__class__!=[].__class__ and yticks.__class__!=().__class__ and yticks.__class__!=np.array([]).__class__ : + if type(yticks)==type(0) or type(yticks)==type(0.): + xt=np.arange(0,self.R['n'],self.R['n']/int(yticks)) + else : + xt=np.arange(0,self.R['n'],self.R['n']/4) + else : + xt=np.array(yticks) + xt1=np.arange(self.R['n']) + if _yticks : + yt1=self.M['_row_values'][:,0] + else : + yt1=self.M['_row_index'][:,0] + plt.yticks(xt,interp(xt,xt1,yt1)) + plt.title(title) + if DrawOrShow.lower().strip()=='show' : + plt.show() + else : + plt.draw() + def contour(self,arg,Levels=None,labelLevels=True,lw=2,colors='k') : + """overlaps a contour plot over an imshow + returns Contours Object and Labels Object + """ + from matplotlib import pyplot as plt + CS=plt.contour(self['_col_index'],self['_row_index'],self[arg],Levels,linewidth=lw,colors=colors) + if not labelLevels : + return CS, None + h=plt.clabel(CS) + return CS,h + def radius(self,shape1=False,row0=0.,col0=0.) : + """returns a map with the radii of the map with respect to the center""" + if shape1 : + r=((self.M['_row_values']-self.center[0]-row0)**2+(self.M['_col_values']-self.center[0]-col0)**2)**0.5 + r.shape=r.shape[0]*r.shape[1] + return r + return ((self.M['_row_values']-self.center[0]-row0)**2+(self.M['_col_values']-self.center[0]-col0)**2)**0.5 + def gaussian(self,sigma,row0=0.,col0=0.,normalized=True) : + """returns a gaussian based on map + + normalized = True (default) to have a distribution whose integral is 1 + """ + import numpy as np + return np.exp(-0.5*(self.radius(row0=row0,col0=col0)/sigma)**2)*(1./(2*np.pi*sigma**2) if normalized else 1.) + def elliptic_gaussian(self,sigma_xx,sigma_yy,row0=0.,col0=0.,normalized=True,sigma_xy=None) : + """returns a elliptical gaussian based on map + given sigma_xx, sigma_xy and sigma_yy (squared values) + sigma_xy is passed as a keyword, defaul 0 + + normalized = True (default) to have a distribution whose integral is 1 + """ + import numpy as np + X = (self.M['_row_values']-self.center[0]-row0) + Y = (self.M['_col_values']-self.center[0]-col0) + a=X**2/sigma_xx + b=X*Y/sigma_xy if sigma_xy != None else 0. + c=Y**2/sigma_yy + if normalized : + n=sigma_xx*sigma_yy + n+=-sigma_xy*sigma_xy if sigma_xy != None else 0. + n=2*np.pi*n**0.5 + else : + n=1 + return np.exp(-0.5*(a+b+c))/n + def cutted_map(self,mapname,innerCut=None,outerCut=None,cuttedValue=0.,acceptOutside=False): + """returns a map cutted in circle for radii smaller than a innerCut or larger than outerCut + acceptOutside=True reverses the logic + """ + if self.naxis != 2 : raise Error("cutted_map is defined just for naxis=2") + import numpy as np + import copy + if type(mapname) == type('') : + cmap=copy.deepcopy(self[mapname]) + else : + cmap=copy.deepcopy(mapname) + if outerCut == None and innerCut == None : return cmap + shape2=cmap.shape + shape1=cmap.shape[0]*cmap.shape[1] + radius=self.radius() + radius.shape=shape1 + flag=np.zeros(len(radius)) + if outerCut != None : + flag+=outerCut<radius + if innerCut != None : + flag+=radius < innerCut + if acceptOutside : flag = flag==0 + idx=np.where(flag!=0)[0] + if len(idx) == 0 : + return cmap + elif len(idx) == shape1 : + return cmap*0+cuttedValue + else : + cmap.shape=shape1 + cmap[idx]=cuttedValue + cmap.shape=shape2 + return cmap + def cellArea(self) : + "returns the area of a cell" + return self.C['delta']*self.R['delta'] + def trapz2dWeights(self) : + "returns the trapezoidal integration weights matrix" + weights=np.ones([self.C['n'],self.R['n']])*4. + weights[0:self.C['n'],0]=2. + weights[0:self.C['n'],self.R['n']-1]=2. + weights[0,0:self.R['n']]=2. + weights[self.C['n']-1,0:self.R['n']]=2. + weights[0,0]=1. + weights[self.C['n']-1,0]=1. + weights[self.C['n']-1,self.R['n']-1]=1. + weights[0,self.R['n']-1]=1. + return weights + def trapz2d(self,mapname,doNotScaleByCellArea=False,sortArray=True,returnItg=False,innerCut=None,outerCut=None) : + """returns the trapzd 2d integration of a map + doNotScaleByCellArea = True the result is not multiplied by the area of the cell + """ + import numpy as np + w=self.trapz2dWeights()*0.25 + if not doNotScaleByCellArea : w*=self.cellArea() + if type(mapname) == type('') : + itg=self.cutted_map(w*self[mapname],innerCut=innerCut,outerCut=outerCut,cuttedValue=0.) + else : + itg=self.cutted_map(w*mapname,innerCut=innerCut,outerCut=outerCut,cuttedValue=0.) + if returnItg : return itg + itg.shape=itg.shape[0]*itg.shape[1] + if sortArray : return np.sort(itg).sum() + return itg.sum() + def simpson2dWeights(self,scaledWeights=False) : + """returns the sympson integration weights matrix + simpson integration for a matrix M is (weights*M).sum()*cellArea/9, + if scaledWeights == False (default) the weighted matrix is not scaled by cellArea/9, otherwise it is scaled + """ + import numpy as np + from numpy import where,mod + w=[] + row=np.zeros(self.C['n']) ; idx=np.arange(len(row)) ; row[where(mod(idx,2))[0]]=4 ; row[where(mod(idx,2)==0)[0]]=2 ; row[0]=1; row[-1]=1 ; w.append(row) + for r in range(1,self.R['n']-2) : + if mod(r,2)==1 : + row=np.zeros(self.C['n']) ; idx=np.arange(len(row)) ; row[where(mod(idx,2))[0]]=16 ; row[where(mod(idx,2)==0)[0]]=8 ; row[0]=4; row[-1]=4 ; w.append(row) + else : + row=np.zeros(self.C['n']) ; idx=np.arange(len(row)) ; row[where(mod(idx,2))[0]]=8 ; row[where(mod(idx,2)==0)[0]]=4 ; row[0]=2; row[-1]=2 ; w.append(row) + row=np.zeros(self.C['n']) ; idx=np.arange(len(row)) ; row[where(mod(idx,2))[0]]=16 ; row[where(mod(idx,2)==0)[0]]=8 ; row[0]=4; row[-1]=4 ; w.append(row) + row=np.zeros(self.C['n']) ; idx=np.arange(len(row)) ; row[where(mod(idx,2))[0]]=4 ; row[where(mod(idx,2)==0)[0]]=2 ; row[0]=1; row[-1]=1 ; w.append(row) + if scaledWeights : return np.array(w)*self.cellArea()/9. + return np.array(w) + def simpson2d(self,mapname,doNotScaleByCellArea=False,sortArray=True,returnItg=False,innerCut=None,outerCut=None) : + """returns the sympson 2d integration of a map + doNotScaleByCellArea = True the result is not multiplied by the area of the cell + """ + import numpy as np + w=self.simpson2dWeights()*1./9. + if not doNotScaleByCellArea : w*=self.cellArea() + if type(mapname) == type('') : + itg=self.cutted_map(w*self[mapname],innerCut=innerCut,outerCut=outerCut,cuttedValue=0.) + else : + itg=self.cutted_map(w*mapname,innerCut=innerCut,outerCut=outerCut,cuttedValue=0.) + if returnItg : return itg + itg.shape=itg.shape[0]*itg.shape[1] + if sortArray : return np.sort(itg).sum() + return itg.sum() + def copy_map(self,mapname) : + "returns a copy of map mapname" + import copy + try : + return copy.deepcopy(self.M[mapname]) + except : + return + def add_dbi_map(self,mapname,newmap_name=None) : + "adds the dbi map of the mapname map, the name of the new map is dbi-mapname" + import numpy as np + _new = newmap_name if newmap_name!=None and newmap_name!='' else 'dbi-'+mapname + try : + self.M[_new]=10*np.log10(self[mapname]) + except : + raise Error("Impossible to create %s "%_new) + return None + if self.isVerbose() : "Created %s "%_new + return _new + def minimax(self,mapname) : + "return min and max values of map mapname avoiding NaN and infinite numbers" + import numpy as np + a=self.copy_map(mapname) + if a == None : return None + a.shape=a.shape[0]*a.shape[1] + idx=np.where(np.isfinite(a)*(1-np.isnan(a)))[0] + if idx == None : return None + if len(idx) == 0 : return None + return a[idx].min(),a[idx].max() + def finitePixels(self,mapname,return_idx=False) : + "returns the list of pixels which are finite" + import numpy as np + a=self.copy_map(mapname) + if a == None : return None + a.shape=a.shape[0]*a.shape[1] + idx=np.where(np.isfinite(a)*(1-np.isnan(a)))[0] + return idx + def histogram(mapName,levels=None,vmin=None,vmax=None,finite=False,nan=False) : + "returns a fast_histogram object of a map" + return fast_histogram(self[mapName],levels=levels,vmin=vmin,vmax=vmax,finite=finite,nan=nan) + def map2fitsTableColumn(self,arg,fits_type='D') : + "converts a map into a 2d fits column" + import pyfits + fmt=str(self.shape[1])+fits_type + try : + unit=self.unit[arg] + except : + unit='none' + return pyfits.Column(name=arg,unit=unit,format=fmt,array=self[arg]) + def row_fft(self,argument,axis=-1,return_freq=False,shifted=False) : + """returns the row by row FFT of 'argument' + argument can be either a name or matrix + if return_freq=True returns just the frequencies + if shifted=True applies fftshift to have 0 freq at center + """ + import numpy as np + if return_freq : + rf=np.fft.fftfreq(self.SHAPE()[self.C['n']]) + if shifted : + rf=np.fft.fftshift(rf) + return rf + f=self.zeros()*1j + if type(argument) == type('') : + for k in range(self.R['n']) : + f[k]=np.fft.fft(self[argument][k]) + else : + for k in range(self.R['n']) : + f[k]=np.fft.fft(argument[k],axis=-1) + if shifted : + for k in range(self.R['n']) : + f[k]=np.fft.fftshift(f[k],axis=-1) + return f + def row_ifft(self,argument) : + """returns the row by row IFFT of 'argument' + argument can be either a name or matrix + """ + import numpy as np + ift=self.zeros()*1j + if type(argument) == type('') : + for k in range(self.R['n']) : + ift[k]=np.fft.ifft(self[argument][k]) + else : + for k in range(self.R['n']) : + ift[k]=np.fft.ifft(argument[k],axis=-1) + return ift + def fitsTable(self,*arg,**karg) : + """convert to a fits table + doNotAddPrivateTables = True only tables which are not private are added + exclude = list of tables to be excluded + """ + import pyfits + import time + if karg.has_key('doNotAddPrivateTables') : + if karg['doNotAddPrivateTables'] : + lsn=[] + else : + lsn=self.keys(private=True) + else : + lsn=self.keys(private=True) + if karg.has_key('exclude') : + excluded=karg['exclude'] + if len(excluded) == 0 : excluded=None + else : + excluded=None + if len(arg) == 0 : + for k in self.keys() : + lsn.append(k) + else : + for k in arg : + lsn.append(k) + if excluded == None : + names=lsn + else : + names=[] + for k in lsn : + try : + excluded.index(k) + except : + names.append(k) + if self.isVerbose() : + print names + print excluded + thdu=[] + for k in names : + thdu.append(self.map2fitsTableColumn(k)) + fthdu=pyfits.new_table(pyfits.ColDefs(thdu)) + # those general + fthdu.update_ext_name(self.mapname) + fthdu.header.update('mapname',self.mapname,'name of the map') + fthdu.header.update('created',time.asctime()) + fthdu.header.update('row_name',self.R['name'],'name of row') + fthdu.header.update('row_n',self.shape[0],'number of rows in a map') + fthdu.header.update('row_unit',self.R['unit'],'unit of row') + fthdu.header.update('row_min',self.R['min'],'row min value') + fthdu.header.update('row_max',self.R['max'],'row max value') + fthdu.header.update('row_step',self.R['delta'],'row step') + fthdu.header.update('col_name',self.C['name'],'name of col') + fthdu.header.update('col_n',self.shape[1],'number of cols in a map') + fthdu.header.update('col_unit',self.C['unit'],'unit of row') + fthdu.header.update('col_min',self.C['min'],'col min value') + fthdu.header.update('col_max',self.C['max'],'col max value') + fthdu.header.update('col_step',self.C['delta'],'col step') + fthdu.header.update('raster','n','if y maps are rastered') + fthdu.header.add_comment('MapGrid binTable FITS format') + fthdu.header.add_comment('MapGrid ') + fthdu.header.add_comment(' a collection of 2D maps') + fthdu.header.add_comment(' rows are Y values, cols are X values') + fthdu.header.add_comment(' a table is made of row_n x col_n elements') + fthdu.header.add_comment(' first element i 0') + fthdu.header.add_comment(' row is increasing faster') + fthdu.header.add_comment(' it is assumed rows and cols are sampled uniformly') + fthdu.header.add_comment(' but this is not granted, in this case look at') + fthdu.header.add_comment(' _row_values, _col_values tables') + fthdu.header.add_comment('MapGrid binTable FITS format') + fthdu.header.add_comment(' each map is a column of the FITS table') + fthdu.header.add_comment(' see RASTER keyword to know wether 2D') + fthdu.header.add_comment(' maps are stored in raster fashion') + fthdu.header.add_comment(' if rasterized columns are 1D ') + fthdu.header.add_comment(' rows sequentially concatenated') + return fthdu + def get_fitsTable(self,filename,ihdu=1,Verbose=False) : + """gets a fits table""" + import numpy as np + import pyfits + self._p=pyfits.open(filename) + self._h=self._p[ihdu].header + self.mapname=self._h['mapname'] + # + for k in self.C.keys() : + nname='col_'+k + try : + self.C[k]=self._h[nname] + except : + nname='hierarch col_'+k + try : + self.C[k]=self._h[nname] + except : + pass + self.C['v']=np.arange(self.C['n'])/float(self.C['n'])*(self.C['max']-self.C['min'])+self.C['min'] + try : + if not np.isfinite(self.C['delta']) : + self.C['delta']=self.C['v'][1]-self.C['v'][0] + except : + self.C['delta']=self.C['v'][1]-self.C['v'][0] + # + for k in self.R.keys() : + nname='row_'+k + try : + self.R[k]=self._h[nname] + except : + nname='hierarch row_'+k + try : + self.R[k]=self._h[nname] + except : + pass + self.R['v']=np.arange(self.R['n'])/float(self.R['n'])*(self.R['max']-self.R['min'])+self.R['min'] + try : + if not np.isfinite(self.R['delta']) : + self.R['delta']=self.R['v'][1]-self.R['v'][0] + except : + self.R['delta']=self.R['v'][1]-self.R['v'][0] + self.shape=self.SHAPE() + # + for iaxis in range(1,self._h['TFIELDS']+1) : + kTYPE='TTYPE%d'%iaxis + kUNIT='TUNIT%d'%iaxis + nn=self._h[kTYPE].strip() + try : + uu=self._h[kUNIT].strip() + except : + uu='' + if Verbose == True : print iaxis,kTYPE,nn,kUNIT,uu, + self.newmap(nn,value=self._p[ihdu].data[nn],unit=uu) + if Verbose == True : print self[nn].shape,self.SHAPE() + # + try : + self.R['v']=self['_row_values'][:,0] + self.R['v'].shape=self.R['v'].size + self.R['delta']=self.R['v'][1]-self.R['v'][0] + except : + pass + # + try : + self.C['v']=self['_col_values'][0] + self.C['v'].shape=self.C['v'].size + self.C['delta']=self.C['v'][1]-self.C['v'][0] + except : + pass + + +class IndexHDU : + def __init__(self,hdu) : + import copy + if hdu == None : + return + self.extname=copy.deepcopy(hdu.data['extname']) + self.extnum=copy.deepcopy(hdu.data['extnum']) + self.type=copy.deepcopy(hdu.data['type']) + self.comment=copy.deepcopy(hdu.data['comment']) + def __len__(self): + return len(self.extname) + def __getitem__(self,i) : + import numpy + if type(i) == type('') : + idx=numpy.where(self.extname==i)[0] + if len(idx) == 0 : + return [] + return [self.extname[idx],self.extnum[idx],self.type[idx],self.comment[idx]] + try : + idx=i + return [self.extname[idx],self.extnum[idx],self.type[idx],self.comment[idx]] + except : + return [] + def __str__(self) : + for k in range(len(self)) : + print self[k] + def keys(self,pubblic=True) : + import numpy as np + _P=np.array(['ROWIDX','ROWVAL','COLIDX','COLVAL','XAXIS','YAXIS','ZAXIS','PRIMARY','DESCRIPTION','INMAPS']) + if pubblic : + l=[] + for k in self.extname : + if (k.strip().upper() == _P).sum()==0 : + l.append(k.strip()) + return l + return self.extname + +class DescriptionHDU : + "Handles a Description HDU" + def __init__(self,hdu) : + import copy + import numpy + try : + self.name = copy.deepcopy(hdu.data['info']) + self.text = copy.deepcopy(hdu.data['text']) + self.comment = copy.deepcopy(hdu.data['comment']) + except : + self.name = [] + self.text = [] + self.comment = [] + def __len__(self): + return len(self.name) + def __getitem__(self,i) : + import numpy + if type(i) == type('') : + idx=numpy.where(self.name==i)[0] + if len(idx) == 0 : + return [] + return [self.name[idx],self.text[idx],self.comment[idx]] + try : + idx=i + return [self.name[idx],self.text[idx],self.comment[idx]] + except : + return [] + def __str__(self) : + for k in range(len(self)) : + print self[k] + def keys(self,pubblic=True) : + return self.name + def toDict(self) : + return self.__dict__ + +class MapGridCube(MapGrid) : + def __init__(self,*karg,**kopt) : + import numpy as np + import pickle + import pyfits + import copy + import time + if type(karg[0]) == type('') : + tic=time.time() + self.load(karg[0]) + tic=time.time()-tic + self.info['MapGridCube:ReadoutTime']=tic + return + if type(karg[0]) == type(pyfits.HDUList()) : + MapGrid.__init__(self) + self.clean() + hduIndex='index' + self.Index=IndexHDU(karg[0]['index']) + D=DescriptionHDU(karg[0]['description']) + for k in D.keys() : + self.info[k]=D[k][1][0] + self.C=GridAxis(karg[0]['xaxis']).__dict__ + self.R=GridAxis(karg[0]['yaxis']).__dict__ + self.Z=GridAxis(karg[0]['zaxis']).__dict__ + self.shape=(self.Z['n'],self.R['n'],self.C['n']) + self.M['_row_index']=copy.deepcopy(karg[0]['rowidx'].data) + self.unit['_row_index']='' + self.M['_row_values']=copy.deepcopy(karg[0]['rowval'].data) + self.unit['_row_values']=self.R['unit'] + self.M['_col_index']=copy.deepcopy(karg[0]['colidx'].data) + self.unit['_col_index']='' + self.M['_col_values']=copy.deepcopy(karg[0]['colval'].data) + self.unit['_col_values']=self.C['unit'] + for k in self.Index.keys(pubblic=True) : + try : + if karg[0][k].header['xtension'].strip().upper()=='IMAGE' : + try : + name = karg[0][k].header['name'] + except : + name=k + self.M[name]=copy.deepcopy(karg[0][k].data) + try : + self.unit[name]=karg[0][k].header['unit'] + except : + self.unit[name]='' + except : + pass + return + if len(karg) == 3 : + if type(karg[0]) == type(karg[1]) and type(karg[0]) == type(karg[2]) and karg[0].__class__ == GridAxis().__class__ : + MapGrid.__init__(self,*karg[0:2],**kopt) + self.Z=karg[2].__dict__ + self.shape=(self.R['n'],self.C['n'],self.Z['n']) + self.nslices=self.Z['n'] + return + self.Index=None + MapGrid.__init__(self,*karg,**kopt) + def clean(self) : + from numpy import nan,zeros + MapGrid.clean(self) + # the z axis splits the planes + self.Z = self.newaxis() + self.naxis=3 + self.shape=(0,0,0) + def refresh(self) : + "used to refresh interal constants" + self.shape=(self.Z['n'],self.R['n'],self.C['n']) + def isflat(self,name) : + if type(name) == type('') : + return len(self.M[name].shape) == 2 + return len(name.shape) == 2 + def newmap(self,name,unit='',value=None,dtype='float',flat=False) : + from numpy import nan,zeros + if flat : + self.M[name] = zeros([self.R['n'],self.C['n']],dtype=dtype) + else : + self.M[name] = zeros([self.Z['n'],self.R['n'],self.C['n']],dtype=dtype) + self.unit[name] = unit + if value == None : + if type(dtype) == type('') : + if dtype.strip() !='int' : + self.M[name] += nan + else : + if dtype != type(1) : + self.M[name] += nan + else : + self.M[name] += value + def transpose(self) : + import copy + from numpy import transpose + M = MapGridCube() + M.info = copy.deepcopy(self.info) + M.unit = copy.deepcopy(self.unit) + M.R = copy.deepcopy(self.C) + M.C = copy.deepcopy(self.R) + M.Z = copy.deepcopy(self.Z) + M.shape=[M.Z['n'],M.R['n'],M.C['n']] + for k in self.M.keys() : + if self.isflat(k) : + M.M[k]=transpose(self.M[k][iz]) + for iz in range(M.Z['n']) : + M.M[k][iz]=transpose(self.M[k][iz]) + return M + def __getitem__(self,*args) : + print args,len(args) + if len(args) == 1 : + try : + return self.M[args[0]] + except : + raise Error("invalid argument") + elif len(args) == 2 : + try : + return self.M[args[0]][args[1]] + except : + raise Error("invalid argument") + elif len(args) == 3 : + try : + return self.M[args[0]][args[1]][args[2]] + except : + raise Error("invalid argument") + elif len(args) == 4 : + try : + return self.M[args[0]][args[1]][args[2]][args[3]] + except : + raise Error("invalid argument") + else : + raise Error("invalid argument") + def __setitem__(self,*args) : + if len(args) == 2 : + try : + self.M[args[0]]=copy.deepcopy(args[1]) + except : + raise Error("invalid argument") + elif len(args) == 3 : + try : + self.M[args[0]][args[1]]=copy.deepcopy(args[2]) + except : + raise Error("invalid argument") + elif len(args) == 4 : + try : + self.M[args[0]][args[1]][args[2]]=copy.deepcopy(args[3]) + except : + raise Error("invalid argument") + elif len(args) == 5 : + try : + self.M[args[0]][args[1]][args[2]][args[3]]=copy.deepcopy(args[4]) + except : + raise Error("invalid argument") + else : + raise Error("invalid argument") + def set_z_scale(self,*karg) : + """ set_z_scale(string name) + set_z_scale(string name,string unit) + set_z_scale(string name,string unit,array values) + set_z_scale(string name,string unit,float min, float max, int n) + set_z_scale(string name,string unit,float min, float max, float delta) + """ + from numpy import nan,zeros,array,round + self.Z['closed']=False + self.Z['name']=karg[0] + if len(karg) < 2 : + return + self.Z['unit']=karg[1] + if len(karg) < 3 : + return + self.shape[0]=0 + if type(karg[2]) == type(array([])) : + self.Z['v'] = 1.*karg[2] + self.Z['min'] = self.Z['v'].min() + self.Z['max'] = self.Z['v'].max() + self.Z['n'] = len(self.Z['v']) + self.Z['delta'] = self.Z['v'][1]-self.Z['v'][0] + else : + if len(karg) < 4 : + print "error: not enough arguments" + return + self.Z['min']=karg[2] + self.Z['max']=karg[3] + if type(karg[4]) == type(1) : + self.Z['n']=karg[4] + self.Z['delta']=(karg[3]-karg[2])/float(karg[4]) + else : + self.Z['delta']=karg[4] + self.Z['n']=int(round((karg[3]-karg[2])/float(karg[4]))) + self.shape[0]=self.Z['n']*1 + if self.shape[0]*self.shape[1] > 0: + self.clean_matrices() + def bilinearXY(self,component,x_col,y_row,returnVal=None,returnDelta=False) : + naxis=self.naxis + self.naxis = 2 + f=MapGrid.bilinearXY(self,component,x_col,y_row,returnVal=returnVal,returnDelta=returnDelta) + self.naxis = naxis + return f + def profile(self,name,x1_col,y1_col,x2_col,y2_col,nsmp=100) : + "returns a profile along a line" + #computes line coefficients + import numpy as np + l=np.arange(nsmp)/float(nsmp-1) + x_col=(x2_col-x1_col)*l+x1_col + y_col=(y2_col-y1_col)*l+y1_col + f=self.bilinearXY(name,x_col,y_col) + return {'l':l,'x':x_col,'y':y_col,'p':f} + +if __name__=='__main__' : + import numpy as np + + #test creation empty map + print "test creation empty map" + GMEmpty = MapGrid(mapname='GMEmpty') + + #test creation map with shape [100,200] + GM12=MapGrid(Rows=100,Cols=200,mapname='GM12') + + #test creation map with GridAxis + GMD12=MapGrid(Cols=GridAxis('x','deg',np.arange(0.,360.,1.),periodic=True),Rows=GridAxis('y','deg',np.arange(-18.,19.,1.)),mapname='GMD12') + + #test creation map with GridAxis + GMA12=MapGrid(Cols=np.arange(-10,11,1.),Rows=np.arange(22,-1,-1),mapname='GMA12') + + #test creation map with model + GMM12=MapGrid(model=GMA12['_row_values']**2+GMA12['_col_values']**2) + + stop + + GM=MapGrid(GridAxis('x','deg',arange(0.,360.,1.,period=True)),GridAxis('y','deg',arange(-18.,19.,1.))) + GM.M['sinCol']=np.sin(np.deg2rad(GM['_col_values'])) + + print "Test X_col interpolation" + x_col=arange(0.,360.1,0.1) + Test1={} + Test1['interpolated']=GM.bilinearXY('sinCol',x_col,0.*x_col) + Test1['calculated']=np.sin(np.deg2rad(x_col)) + Test1['simulated interpolation']=(np.sin(np.deg2rad(np.floor(x_col)+1))-np.sin(np.deg2rad(np.floor(x_col))))*(x_col-np.floor(x_col))/1.+np.sin(np.deg2rad(np.floor(x_col))) + Test1['interpolated-calculated']=Test1['interpolated']-Test1['calculated'] + Test1['simulated interpolation-calculated']=Test1['simulated interpolation']-Test1['calculated'] + Test1['simulated interpolation-interpolated']=Test1['simulated interpolation']-Test1['interpolated'] + + for k in ['interpolated-calculated', 'simulated interpolation-calculated', 'simulated interpolation-interpolated'] : + print "abs(%20s) = %e,%e"%(k,abs(Test1[k]).min(),abs(Test1[k]).max()) + print + + print "Test X_col and Y_col interpolation" + y_row=0.1*arange(361,dtype='int')+GM.R['min'] + x_col2=y_row*0.+90. + GM.M['AsinCol']=np.sin(np.deg2rad(GM['_col_values']))*GM['_row_values'] + Test2={} + Test2['interpolated']=GM.bilinearXY('AsinCol',x_col2,y_row) + Test2['calculated']=np.sin(np.deg2rad(x_col2))*y_row + #Test2['simulated interpolation']=((np.floor(x_col2)+1)*np.sin(np.deg2rad(np.floor(x_col2)+1))-np.floor(x_col2)*np.sin(np.deg2rad(np.floor(x_col2))))*(x_col2-np.floor(x_col2))/1.+np.floor(x_col2)*np.sin(np.deg2rad(np.floor(x_col2))) + Test2['interpolated-calculated']=Test2['interpolated']-Test2['calculated'] + #Test2['simulated interpolation-calculated']=Test2['simulated interpolation']-Test2['calculated'] + #Test2['simulated interpolation-interpolated']=Test2['simulated interpolation']-Test2['interpolated'] + #for k in ['interpolated-calculated', 'simulated interpolation-calculated', 'simulated interpolation-interpolated'] : + for k in ['interpolated-calculated' ] : + print "abs(%20s) = %e,%e"%(k,abs(Test2[k]).min(),abs(Test2[k]).max()) + + + diff --git a/src/yapsut/grep.py b/src/yapsut/grep.py new file mode 100644 index 0000000000000000000000000000000000000000..32a84d2e12eb7768dbb95d2896094f0e790f87b8 --- /dev/null +++ b/src/yapsut/grep.py @@ -0,0 +1,25 @@ +__DESCRIPTION__="GREP like codes (from http://casa.colorado.edu/~ginsbura/pygrep.htm)" + +def simple(string,list): + """a simple grep""" + import re + expr = re.compile(string) + l=[] + for text in list: + match = expr.search(text) + if match != None: + l.append(match.string) + return l + +def exact(string,list): + """return just exact matches""" + import re + expr = re.compile(string) + return [elem for elem in list if expr.match(elem)] + +def substring(string,list): + """return any item containing the search string as a substring in any position""" + import re + expr = re.compile(string) + return filter(expr.search,list) + diff --git a/src/yapsut/intervalls.py b/src/yapsut/intervalls.py new file mode 100644 index 0000000000000000000000000000000000000000..859c4d8488c65ed4b2e490f2022a1c8f2376d7fd --- /dev/null +++ b/src/yapsut/intervalls.py @@ -0,0 +1,73 @@ +import numpy as np + +class intervalls() : + """ A class to handle intervalls. + + Usage: + v = [0,1,2,3,5,6,7] + ITV = intervalls(v) + + for i in ITV : + print(i) + + will result in printing + (0,3) + (5,7) + + print ITV[0] + + will result in printing + (0,3) + """ + def __init__(self,v,dv=1) : + self._current = -1 + if v == None : + self.inf=[] + self.sup=[] + else : + if len(v) == 0 : + self.inf=[] + self.sup=[] + else : + self.inf = [v[0]] + self.sup = [] + vlast = v[0] + for i in range(1,len(v)) : + if v[i]-vlast <= dv : + vlast = v[i] + else : + self.sup.append(vlast) + self.inf.append(v[i]) + vlast = v[i] + self.sup.append(v[len(v)-1]) + self.inf = np.array(self.inf) + self.sup = np.array(self.sup) + def __len__(self) : + return len(self.inf) + def __iter__(self) : + return self + def __getitem__(self,idx) : + if len(self.inf) < 0 : + raise NameError("Empty Intervalls") + return (self.inf[idx], self.sup[idx]) + def next(self) : + if self._current >= len(self.inf)-1 : + self._current = -1 + raise StopIteration + else : + self._current += 1 + return (self.inf[self._current], self.sup[self._current]) + def arange(self,idx) : + import numpy as np + if len(self.inf) < 0 : + raise NameError("Empty Intervalls") + return np.arange(self.inf[idx], self.sup[idx]+1) + +def _TEST_intervalls() : + v = [0,1,2,3,5,6,7] + ITV = intervalls(v) + for i in ITV : + print(i) + print (ITV[1]) +#_TEST_intervalls() +