00001 """
00002 Converters for linear operators
00003 """
00004
00005 __copyright__ = """
00006 Copyright 2008 Sean Ross-Ross
00007 """
00008 __license__ = """
00009 This file is part of SLIMpy .
00010
00011 SLIMpy is free software: you can redistribute it and/or modify
00012 it under the terms of the GNU Lesser General Public License as published by
00013 the Free Software Foundation, either version 3 of the License, or
00014 (at your option) any later version.
00015
00016 SLIMpy is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 GNU Lesser General Public License for more details.
00020
00021 You should have received a copy of the GNU Lesser General Public License
00022 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00023 """
00024
00025 from slimpy_base.api.Plugins.slim2rsf.sfCommandFactory import rsfCommandFactory
00026
00027 from contourlet import surfSpaceChange, surfInvSpaceChange
00028
00029 from curvelet import GetShapeFwd, GetShapeInv
00030 from curvelet import GetShapeFwd3d, GetShapeInv3d
00031
00032 from numpy import ceil
00033 from pad import ( padHelper,
00034 padAdjHelper,
00035 padReplaceHelper )
00036
00037 from sfConverter import sfConverter
00038
00039 class all( object ):
00040
00041 class fft1( sfConverter ):
00042 @classmethod
00043 def map( cls, source, command ):
00044 command = cls.default_function( command, "fft1" )
00045 command = cls.truefalseHelper( command )
00046 command.kparams['inv'] = command.kparams['adj']
00047 command.kparams.pop( 'adj', None )
00048
00049 return cls.pack( command )
00050
00051 @classmethod
00052 def trans( cls, command, space, *spaces ):
00053 n1 = spaces[0]['n1']
00054 space['n1_fft']= n1
00055 space["n1"] = int( ceil( n1/2. )+1 )
00056 space['data_type']='complex'
00057 return space
00058
00059 @classmethod
00060 def trans_adj( cls, command, space, *spaces ):
00061 n1 = spaces[0]['n1_fft']
00062 space['data_type']='float'
00063 space['n1']= n1
00064 return space
00065
00066 @classmethod
00067 def constr( cls, command, space ):
00068 cls.match( space, data_type='float' )
00069 @classmethod
00070 def constr_adj( cls, command, space ):
00071 cls.match( space, data_type='complex' )
00072
00073 class fft( sfConverter ):
00074 @classmethod
00075 def map( cls, source, command ):
00076 command = cls.default_function( command, "fft3" )
00077 command = cls.truefalseHelper( command )
00078 command.kparams['inv'] = command.kparams['adj']
00079 command.kparams.pop( 'adj', None )
00080 return cls.pack( command )
00081 @classmethod
00082 def trans( cls, cmd, space, spaces ):
00083 return space
00084
00085 class dwt( sfConverter ):
00086 @classmethod
00087 def map( cls, src, cmd ):
00088 cmd = cls.default_function( cmd )
00089 cmd = cls.truefalseHelper( cmd )
00090 return cls.pack( cmd )
00091
00092 @classmethod
00093 def trans( cls, command, space, *spaces ):
00094 return space
00095
00096 class mdwt1( sfConverter ):
00097 @classmethod
00098 def map( cls, src, cmd ):
00099 cmd = cls.default_function( cmd )
00100 cmd = cls.truefalseHelper( cmd )
00101 return cls.pack( cmd )
00102
00103 @classmethod
00104 def trans( cls, command, space, *spaces ):
00105 return space
00106
00107 class mrdwt1( sfConverter ):
00108 @classmethod
00109 def map( cls, src, cmd ):
00110 cmd = cls.default_function( cmd )
00111 cmd = cls.truefalseHelper( cmd )
00112 return cls.pack( cmd )
00113
00114 @classmethod
00115 def trans( cls, command, space, *spaces ):
00116 return space
00117
00118 class daubcqf( sfConverter ):
00119 @classmethod
00120 def map( cls, src, cmd ):
00121 cmd = cls.default_function( cmd )
00122 cmd = cls.truefalseHelper( cmd )
00123 cmd.kparams.pop( 'adj', None )
00124 return cls.pack( cmd )
00125
00126 @classmethod
00127 def trans( cls, command, space, *spaces ):
00128 return space
00129
00130 class fdct2( sfConverter ):
00131 """
00132 This is a mapping instance that maps a SLIMpy command into an object that
00133 can be run
00134 This also maps the agruments and keyword arguments to be pugin specific
00135 """
00136
00137 @classmethod
00138 def map( cls, source, command ):
00139 """
00140 map a SLIMpy command to a rsf command
00141 """
00142
00143
00144
00145
00146 command = cls.keywordmap(command, {'adj':'inv'} )
00147 command = cls.default_function( command, "fdct2left" )
00148 command.kparams.pop( 'cpxIn' ,None)
00149
00150
00151
00152
00153 command = cls.truefalseHelper( command )
00154
00155
00156 return cls.pack( command )
00157
00158 @classmethod
00159 def map_adj( cls, source, command ):
00160 """
00161 map a SLIMpy command to a rsf command
00162 """
00163
00164
00165
00166
00167 command = cls.keywordmap(command, {'adj':'inv'} )
00168 cpxIn = command.kparams.pop( 'cpxIn' ,False)
00169
00170
00171 command = cls.truefalseHelper( command )
00172
00173 if cpxIn:
00174 command = cls.default_function( command, "fdct2" )
00175 else:
00176 c1, c2 = cls.split( command )
00177 c1 = cls.default_function( c1, "fdct2" )
00178 c2 = cls.keep( c2, [] )
00179 c2 = cls.default_function( c2, "real" )
00180 command = [ c1, c2 ]
00181
00182 return cls.pack( command )
00183
00184 @classmethod
00185 def trans( cls, command, space, *spaces ):
00186
00187 shape = GetShapeFwd( command, space )
00188
00189 space['N1'] = space['n1']
00190 space['N2'] = space['n2']
00191
00192 space['n1'] = shape[0]
00193 space['n2'] = 1
00194
00195 space['nbs'] = command['nbs']
00196 space['nba'] = command['nba']
00197 space['ac'] = command['ac']
00198
00199 space['data_type'] = 'complex'
00200 return space
00201
00202 @classmethod
00203 def trans_adj( cls, command, space, *spaces ):
00204 shape = GetShapeInv( command, space )
00205
00206 space['n1'] = shape[0]
00207 space['n2'] = shape[1]
00208 if command['cpxIn']:
00209 pass
00210 else:
00211 space['data_type'] = 'float'
00212 return space
00213
00214 @classmethod
00215 def constr( cls, command, space ):
00216 cls.match( space, data_type='float' )
00217 if not space.ndim == 2:
00218 raise Exception("wrong number of dimentions for fdct2 got %s" %( space.ndim ) )
00219
00220 @classmethod
00221 def constr_adj( cls, command, space ):
00222 pass
00223
00224 class fdct3( sfConverter ):
00225 @classmethod
00226 def map( cls, source, command ):
00227
00228
00229 command = cls.keywordmap(command, {'adj':'inv'} )
00230 command = cls.default_function( command, "fdct3" )
00231 command.kparams.pop( 'cpxIn' ,None)
00232
00233 command = cls.truefalseHelper( command )
00234
00235
00236 return cls.pack( command )
00237
00238 @classmethod
00239 def map_adj( cls, source, command ):
00240 """
00241 map a SLIMpy command to a rsf command
00242 """
00243
00244
00245
00246
00247 command = cls.keywordmap(command, {'adj':'inv'} )
00248 cpxIn = command.kparams.pop( 'cpxIn' ,False)
00249
00250
00251 command = cls.truefalseHelper( command )
00252
00253 if cpxIn:
00254 command = cls.default_function( command, "fdct3" )
00255 else:
00256 c1, c2 = cls.split( command )
00257 c1 = cls.default_function( c1, "fdct3" )
00258 c2 = cls.keep( c2, [] )
00259 c2 = cls.default_function( c2, "real" )
00260 command = [ c1, c2 ]
00261
00262 return cls.pack( command )
00263
00264
00265
00266
00267
00268
00269
00270
00271 @classmethod
00272 def trans( cls, command, space, *spaces ):
00273 space['data_type'] = 'complex'
00274
00275
00276 shape = GetShapeFwd3d( command, space )
00277
00278 space['N1'] = space['n1']
00279 space['N2'] = space['n2']
00280 space['N3'] = space['n3']
00281
00282 space.shape = shape
00283
00284
00285 space['nbs'] = command['nbs']
00286 space['nbd'] = command['nbd']
00287 space['ac'] = command['ac']
00288
00289 return space
00290
00291 @classmethod
00292 def trans_adj( cls, command, space, *spaces ):
00293
00294 shape = GetShapeInv3d( command, space )
00295
00296 space.shape = shape
00297
00298 if command['cpxIn']:
00299 pass
00300
00301 else:
00302 space['data_type'] = 'float'
00303 return space
00304
00305 @classmethod
00306 def constr( cls, command, space ):
00307 pass
00308
00309
00310
00311
00312
00313 @classmethod
00314 def constr_adj( cls, command, space ):
00315 cls.match( space, data_type='complex' )
00316
00317 class fdct( sfConverter ):
00318 """
00319 The fast discrete curvelet transform in-core with PYCT (sffdct)
00320 """
00321 @classmethod
00322 def map( cls, source, command ):
00323 command = cls.default_function( command, "fdct" )
00324
00325 command = cls.truefalseHelper( command )
00326 command.kparams.pop( 'curveSpace' )
00327
00328 return cls.pack( command )
00329
00330 @classmethod
00331 def trans( cls, command, space, *spaces ):
00332 space['sizes'] = (space['n1'],space['n2'])
00333
00334 if command.kparams['curveSpace'] != None:
00335 space['n1'] = command.kparams['curveSpace']['n1']
00336 space['n2'] = 1
00337
00338 return space
00339
00340 @classmethod
00341 def trans_adj( cls, command, space, *spaces ):
00342 space['n1'] = spaces[0]['sizes'][0]
00343 space['n2'] = spaces[0]['sizes'][1]
00344
00345 return space
00346
00347 class surf( sfConverter ):
00348 @classmethod
00349 def map( cls, source, command ):
00350 command = cls.default_function( command, "surf" )
00351 command = cls.truefalseHelper( command )
00352 command.kparams.pop('inv', None )
00353 return cls.pack( command )
00354
00355 @classmethod
00356 def map_adj( cls, source, command ):
00357 command = cls.default_function( command, "surf" )
00358 command = cls.truefalseHelper( command )
00359
00360 if command.kparams.has_key( 'inv' ):
00361 if command.kparams['inv'] == 'n':
00362 command.kparams.pop('inv', None )
00363 elif command.kparams['inv'] == 'y':
00364 command.kparams.pop('adj', None )
00365
00366 return cls.pack( command )
00367
00368 @classmethod
00369 def trans( cls, command, space, *spaces ):
00370 surfSpaceChange( command, space, *spaces )
00371 return space
00372
00373 @classmethod
00374 def trans_adj( cls, command, space, *spaces ):
00375 surfInvSpaceChange( command, space, *spaces )
00376 return space
00377
00378 class pad( sfConverter ):
00379 @classmethod
00380 def map( cls, src, cmd ):
00381 cmd = cls.default_function( cmd, "pad" )
00382 cmd = cls.truefalseHelper( cmd )
00383 cmd.kparams.pop( 'adj' )
00384 return cls.pack( cmd )
00385
00386 @classmethod
00387 def map_adj( cls, src, cmd ):
00388 cmd = cls.default_function( cmd, "window" )
00389 cmd = cls.truefalseHelper( cmd )
00390 cmd = padReplaceHelper( cmd , src.params )
00391 cmd.kparams.pop( 'adj' )
00392 cmd.kparams[ 'squeeze'] = 'n'
00393 return cls.pack( cmd )
00394
00395 @classmethod
00396 def trans( cls, command, space, *spaces ):
00397 padHelper( command, space, *spaces )
00398 return space
00399
00400 @classmethod
00401 def trans_adj( cls, command, space, *spaces ):
00402 padAdjHelper( command, space, *spaces )
00403 return space
00404
00405 class mig( sfConverter ):
00406 @classmethod
00407 def map( cls, src, cmd ):
00408 cmd = cls.default_function( cmd, "rtmig" )
00409 cmd = cls.truefalseHelper( cmd )
00410 cmd.kparams.pop( 'modelSpace' )
00411 cmd.kparams.pop( 'dataSpace' )
00412 return cls.pack( cmd )
00413
00414 @classmethod
00415 def trans( cls, command, space, *spaces ):
00416 space['n1'] = command.kparams['dataSpace']['n1']
00417 space['n2'] = command.kparams['dataSpace']['n2']
00418 space['d1'] = command.kparams['dataSpace']['d1']
00419 space['d2'] = command.kparams['dataSpace']['d2']
00420 return space
00421
00422 @classmethod
00423 def trans_adj( cls, command, space, *spaces ):
00424 space['n1'] = command.kparams['modelSpace']['n1']
00425 space['n2'] = command.kparams['modelSpace']['n2']
00426 space['d1'] = command.kparams['modelSpace']['d1']
00427 space['d2'] = command.kparams['modelSpace']['d2']
00428 return space
00429
00430 @classmethod
00431 def constr( cls, command, space ):
00432 cls.match( space, data_type='float' )
00433
00434 @classmethod
00435 def constr_adj( cls, command, space ):
00436 cls.match( space, data_type='float' )
00437
00438 class dipfilter( sfConverter ):
00439 @classmethod
00440 def map(cls, src, cmd):
00441 cmd = cls.default_function( cmd, "dipfilter" )
00442 cmd.kparams.pop( 'adj' )
00443 return cls.pack( cmd )
00444
00445 @classmethod
00446 def map_adj(cls, src, cmd):
00447 cmd.kparams.pop( 'adj' )
00448 c1, c2 = cls.split( cmd )
00449
00450 c2 = cls.default_function( c2, 'conj' )
00451 c2 = cls.keep( c2, [] )
00452 c2.kparams['output'] = 'conj(input)'
00453
00454 c1 = cls.default_function( c1, "dipfilter" )
00455 c2 = cls.default_function( c2, "math" )
00456 return cls.pack( [c1, c2] )
00457
00458 @classmethod
00459 def constr( cls, command, space ):
00460 cls.match( space, data_type='complex' )
00461
00462 @classmethod
00463 def trans( cls, command, space, *spaces ):
00464 return space
00465
00466 class pick( sfConverter ):
00467 @classmethod
00468 def map( cls, src, cmd ):
00469 cmd = cls.default_function( cmd, "headercut" )
00470 cmd.kparams.pop( 'adj' )
00471 return cls.pack( cmd )
00472
00473 @classmethod
00474 def trans( cls, command, space, *spaces ):
00475 return space
00476
00477 @classmethod
00478 def constr( cls, command, space ):
00479 mask_shape = command['mask'].params.shape
00480 exp_ndim = len(space.shape)-1
00481 ndim = len( mask_shape )
00482 assert ndim == exp_ndim , "mask must be one dimension less than the data - got %(ndim)s, expected %(exp_ndim)s" %vars()
00483 msg = "mask's n1 must equal data's n2, got mask n1=%s data n2=%s"
00484 assert mask_shape[0] == space.shape[1], msg %(mask_shape[0],space.shape[1])
00485 pass
00486
00487 class restrict( sfConverter ):
00488 @classmethod
00489 def map( cls, src, cmd ):
00490 cmd = cls.default_function( cmd, "headerwindow" )
00491 cmd.kparams.pop( 'adj' )
00492 return cls.pack( cmd )
00493
00494 @classmethod
00495 def trans( cls, command, space, *spaces ):
00496
00497
00498 return space
00499
00500 class sort( sfConverter ):
00501 @classmethod
00502 def map( cls, src, cmd ):
00503
00504 cmd = cls.default_function( cmd )
00505 cmd = cls.truefalseHelper( cmd )
00506
00507 shape = cls.shape( src.params )
00508 if len(shape) is 0:
00509 pass
00510 elif len(shape) is not 1:
00511 prod = reduce(lambda a,b: a*b, shape)
00512 c1, c2 = cls.split( cmd )
00513 c1 = cls.default_function( c1, 'put' )
00514 lam = lambda i: c1.kparams.__setitem__( 'n%s' %i, 1)
00515 for i in range(len(shape)):
00516 lam( i+1 )
00517 c1.kparams['n1'] = prod
00518 c1 = cls.keep( c1, ['n1', 'n2', 'n3', 'n4', 'n5'] )
00519 cmd = [c1,c2]
00520
00521 return cls.pack( cmd )
00522
00523 @classmethod
00524 def trans( cls, command, space, *spaces ):
00525 return space
00526
00527 class transp( sfConverter ):
00528 @classmethod
00529 def map( cls, src, cmd ):
00530 cmd = cls.default_function( cmd )
00531 cmd.kparams.pop( 'adj', None )
00532 plane = cmd.kparams['plane']
00533 cmd.kparams['plane'] = '%s%s' %( plane[0], plane[1] )
00534 return cls.pack( cmd )
00535
00536 @classmethod
00537 def trans( cls, cmd, space, *spaces ):
00538 a, b = cmd.kparams['plane']
00539
00540 na = "n%(a)s" %vars()
00541 nb = "n%(b)s" %vars()
00542
00543 atmp = space[nb]
00544 space[nb] = space[na]
00545 space[na] = atmp
00546 return space
00547
00548 class halfderiv( sfConverter ):
00549 @classmethod
00550 def map( cls, src, cmd ):
00551 cmd = cls.default_function( cmd, "halfint" )
00552 cmd = cls.truefalseHelper( cmd )
00553 return cls.pack( cmd )
00554
00555 @classmethod
00556 def trans( cls, command, space, *spaces ):
00557 return space
00558
00559 class cosinetrans( sfConverter ):
00560 @classmethod
00561 def map( cls, src, cmd ):
00562
00563 cmd.kparams.pop( 'adj', False )
00564 c1, c2 = cls.split( cmd )
00565
00566 c1 = cls.default_function( c1, "cosft" )
00567
00568
00569 for i in range(src.params.ndim):
00570 c1.kparams["sign%s"%(i+1)] = '1'
00571
00572 c2 = cls.default_function( c2, "math" )
00573 size = src.params.size
00574 c2.kparams['output'] = "input/sqrt(2*%s)" %(size)
00575 return cls.pack( [c1,c2] )
00576
00577 @classmethod
00578 def map_adj( cls, src, cmd ):
00579
00580 cmd.kparams.pop( 'adj', False )
00581 c1, c2 = cls.split( cmd )
00582
00583 c2 = cls.default_function( c2, "cosft" )
00584
00585 c2.kparams.pop( 'adj', False )
00586
00587 for i in range(src.params.ndim):
00588 c2.kparams["sign%s"%(i+1)] = '-1'
00589
00590 c1 = cls.default_function( c1, "math" )
00591 size = src.params.size
00592 c1.kparams['output'] = "input*sqrt(2*%s)" %(size)
00593 return cls.pack( [c1,c2] )
00594
00595
00596 @classmethod
00597 def trans( cls, command, space, *spaces ):
00598 return space
00599
00600 class costaper( sfConverter ):
00601 @classmethod
00602 def map( cls, src, cmd ):
00603 cmd = cls.default_function( cmd, "costaper" )
00604 cmd = cls.truefalseHelper( cmd )
00605 cmd.kparams.pop( 'adj', None )
00606 return cls.pack( cmd )
00607
00608 @classmethod
00609 def trans( cls, command, space, *spaces ):
00610 return space
00611
00612 class taper( sfConverter ):
00613 @classmethod
00614 def map( cls, src, cmd ):
00615 cmd = cls.default_function( cmd, "taper" )
00616 cmd = cls.truefalseHelper( cmd )
00617 cmd.kparams.pop( 'adj', None )
00618 return cls.pack( cmd )
00619
00620 @classmethod
00621 def trans( cls, command, space, *spaces ):
00622 return space
00623
00624 class multpred( sfConverter ):
00625 @classmethod
00626 def map( cls, src, cmd ):
00627 cmd = cls.default_function( cmd, "multpred" )
00628 cmd.kparams['adj'] = 0
00629 return cls.pack( cmd )
00630
00631 @classmethod
00632 def map_adj( cls, src, cmd ):
00633 cmd = cls.default_function( cmd, "multpred" )
00634 cmd.kparams['adj'] = 1
00635 return cls.pack( cmd )
00636
00637 @classmethod
00638 def trans( cls, command, space, *spaces ):
00639 return space
00640
00641 class matrixmult( sfConverter ):
00642 """
00643 This is a mapping instance that maps a SLIMpy command into an object that
00644 can be run
00645 This also maps the agruments and keyword arguments to be pugin specific
00646 """
00647
00648 @classmethod
00649 def map( cls, source, command ):
00650 """
00651 map a SLIMpy command to a rsf command
00652 """
00653
00654 if source.params['data_type'] == 'float':
00655 command = cls.default_function( command, "matmultn" )
00656 elif source.params['data_type'] == 'complex':
00657 command = cls.default_function( command, "matmultn" )
00658
00659 command = cls.truefalseHelper( command )
00660
00661 return cls.pack( command )
00662
00663 @classmethod
00664 def trans( cls, command, space, *spaces ):
00665 mat = command.get_structure('mat').params
00666 space["n1"] = mat["n2"]
00667
00668 return space
00669
00670 @classmethod
00671 def trans_adj( cls, command, space, *spaces ):
00672 mat = command.get_structure('mat')
00673 space["n1"] = mat.params["n1"]
00674
00675 return space
00676
00677 @classmethod
00678 def constr( cls, command, space ):
00679 mat = command.get_structure('mat')
00680 cls.match(space, n1=mat.params["n1"])
00681 cls.eqType(command, (space,mat.params) )
00682
00683 @classmethod
00684 def constr_adj( cls, command, space ):
00685 mat = command.get_structure('mat')
00686 cls.match(space, n1=mat.params["n2"])
00687 cls.eqType(command, (space,mat.params) )
00688
00689 sffactory = rsfCommandFactory()
00690 sffactory.addallfrom( all )