Ignore:
Timestamp:
Mar 26, 2013, 12:06:52 PM (12 years ago)
Author:
aslmd
Message:

UTIL PYTHON planetoplot_v2. Solved a problem with operations: operands were modified, now operations are conservative for operands. Implemented reversed operations for int/float.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UTIL/PYTHON/planetoplot_v2/ppclass.py

    r912 r914  
    201201        return isnum
    202202
    203     # define the operation + on two objects. or with an int/float.
    204     def __add__(self,other):
    205         if self.status == "definedplot":
    206             self.status = "retrieved" # to release a warning so that .defineplot() is done before .makeplot()
    207                                       # ... otherwise operated fields will not be displayed
    208         isnum = self.checktwo(other)
     203    # define a selective copy of a pp() object for operations
     204    # ... copy.copy() is not conservative (still acts like a pointer)
     205    # ... copy.deepcopy() does not work with netCDF objects
     206    # so what is done here is a copy of everything except
     207    # (to avoid sharing with self and therefore modifying self through operations)
     208    # - request attribute of pp() object
     209    # - field attribute of the onerequest() objects
     210    def selective_copy(self):
     211        if self.status in ["init","defined"]:
     212            print "!! ERROR !! Please use .retrieve to get fields for the object you want to copy from." ; exit()
     213        the_clone = pp()
     214        for k, v in vars(self).items():
     215           if k != "request":
     216               setattr(the_clone,k,v)
     217        the_clone.verbose = False
     218        the_clone.define()
    209219        for i in range(self.nfin):
    210220         for j in range(self.nvin):
     
    214224             for x in range(self.nplotx):
    215225              obj = self.request[i][j][t][z][y][x]
    216               if not isnum:   obj2 = other.request[i][j][t][z][y][x]
    217               else:           obj2 = other
    218               if "vector" in self.vargoal[j] + self.filegoal[i]:
    219                   exit() # we do not operate on vectors yet.
    220               else:
    221                   obj = obj + obj2
    222         return self
    223 
    224     # define the operation - on two objects. or with an int/float.
    225     def __sub__(self,other):
    226         if self.status == "definedplot":
    227             self.status = "retrieved" # to release a warning so that .defineplot() is done before .makeplot()
    228                                       # ... otherwise operated fields will not be displayed       
     226              for k, v in vars(obj).items():
     227               if k != "field":
     228                setattr(the_clone,k,v)
     229        the_clone.status = "retrieved"
     230        return the_clone
     231
     232    # define the operation + on two objects. or with an int/float.
     233    # ... with selective_copy the self object is not modified.
     234    def __add__(self,other):
    229235        isnum = self.checktwo(other)
     236        the_clone = self.selective_copy()
    230237        for i in range(self.nfin):
    231238         for j in range(self.nvin):
     
    234241            for y in range(self.nploty):
    235242             for x in range(self.nplotx):
    236               obj = self.request[i][j][t][z][y][x]
    237               if not isnum:   obj2 = other.request[i][j][t][z][y][x]
    238               else:           obj2 = other
     243              obj = the_clone.request[i][j][t][z][y][x]
     244              obj_ref = self.request[i][j][t][z][y][x]
     245              if not isnum:   
     246                  ope = other.request[i][j][t][z][y][x].field
     247                  if obj_ref.field.shape != ope.shape:
     248                    print "!! ERROR !! The two fields for operation do not have the same shape.",self.field.shape,other.field.shape
     249                    exit()
     250              else:           
     251                  ope = other
    239252              if "vector" in self.vargoal[j] + self.filegoal[i]:
    240                   exit() # we do not operate on vectors yet.
     253                  print "!! ERROR !! we do not operate on vectors yet."
     254                  exit()
    241255              else:
    242                   obj = obj - obj2
    243         return self
    244 
    245     # define the operation * on two objects. or with an int/float.
    246     def __mul__(self,other):
    247         if self.status == "definedplot":
    248             self.status = "retrieved" # to release a warning so that .defineplot() is done before .makeplot()
    249                                       # ... otherwise operated fields will not be displayed
     256                  obj.field = obj_ref.field + ope
     257        return the_clone
     258
     259    # define the operation - on two objects. or with an int/float.
     260    # ... with selective_copy the self object is not modified.
     261    def __sub__(self,other):
    250262        isnum = self.checktwo(other)
     263        the_clone = self.selective_copy()
    251264        for i in range(self.nfin):
    252265         for j in range(self.nvin):
     
    255268            for y in range(self.nploty):
    256269             for x in range(self.nplotx):
    257               obj = self.request[i][j][t][z][y][x]
    258               if not isnum:   obj2 = other.request[i][j][t][z][y][x]
    259               else:           obj2 = other
     270              obj = the_clone.request[i][j][t][z][y][x]
     271              obj_ref = self.request[i][j][t][z][y][x]
     272              if not isnum:
     273                  ope = other.request[i][j][t][z][y][x].field
     274                  if obj_ref.field.shape != ope.shape:
     275                    print "!! ERROR !! The two fields for operation do not have the same shape.",self.field.shape,other.field.shape
     276                    exit()
     277              else:
     278                  ope = other
    260279              if "vector" in self.vargoal[j] + self.filegoal[i]:
    261                   exit() # we do not operate on vectors yet.
     280                  print "!! ERROR !! we do not operate on vectors yet."
     281                  exit()
    262282              else:
    263                   obj = obj * obj2
    264         return self
    265 
    266     # define the operation / on two objects. or with an int/float.
    267     def __div__(self,other):
    268         if self.status == "definedplot":
    269             self.status = "retrieved" # to release a warning so that .defineplot() is done before .makeplot()
    270                                       # ... otherwise operated fields will not be displayed
     283                  obj.field = obj_ref.field - ope
     284        return the_clone
     285
     286    # define the operation * on two objects. or with an int/float.
     287    # ... with selective_copy the self object is not modified.
     288    def __mul__(self,other):
    271289        isnum = self.checktwo(other)
     290        the_clone = self.selective_copy()
    272291        for i in range(self.nfin):
    273292         for j in range(self.nvin):
     
    276295            for y in range(self.nploty):
    277296             for x in range(self.nplotx):
    278               obj = self.request[i][j][t][z][y][x]
    279               if not isnum:   obj2 = other.request[i][j][t][z][y][x]
    280               else:           obj2 = other
     297              obj = the_clone.request[i][j][t][z][y][x]
     298              obj_ref = self.request[i][j][t][z][y][x]
     299              if not isnum:
     300                  ope = other.request[i][j][t][z][y][x].field
     301                  if obj_ref.field.shape != ope.shape:
     302                    print "!! ERROR !! The two fields for operation do not have the same shape.",self.field.shape,other.field.shape
     303                    exit()
     304              else:
     305                  ope = other
    281306              if "vector" in self.vargoal[j] + self.filegoal[i]:
    282                   exit() # we do not operate on vectors yet.
     307                  print "!! ERROR !! we do not operate on vectors yet."
     308                  exit()
    283309              else:
    284                   obj = obj / obj2
    285         return self
     310                  obj.field = obj_ref.field * ope
     311        return the_clone
     312
     313    # define the operation / on two objects. or with an int/float.
     314    # ... with selective_copy the self object is not modified.
     315    def __div__(self,other):
     316        isnum = self.checktwo(other)
     317        the_clone = self.selective_copy()
     318        for i in range(self.nfin):
     319         for j in range(self.nvin):
     320          for t in range(self.nplott):
     321           for z in range(self.nplotz):
     322            for y in range(self.nploty):
     323             for x in range(self.nplotx):
     324              obj = the_clone.request[i][j][t][z][y][x]
     325              obj_ref = self.request[i][j][t][z][y][x]
     326              if not isnum:
     327                  ope = other.request[i][j][t][z][y][x].field
     328                  if obj_ref.field.shape != ope.shape:
     329                    print "!! ERROR !! The two fields for operation do not have the same shape.",self.field.shape,other.field.shape
     330                    exit()
     331              else:
     332                  ope = other
     333              if "vector" in self.vargoal[j] + self.filegoal[i]:
     334                  print "!! ERROR !! we do not operate on vectors yet."
     335                  exit()
     336              else:
     337                  obj.field = obj_ref.field / ope
     338        return the_clone
     339
     340    # define the reverse operation float/int + object
     341    def __radd__(self,other):
     342        isnum = self.checktwo(other)
     343        if not isnum: print "!! ERROR !! Operand should be a number" ; exit()
     344        return self.__add__(other)
     345
     346    # define the reverse operation float/int - object
     347    def __rsub__(self,other):
     348        isnum = self.checktwo(other)
     349        if not isnum: print "!! ERROR !! Operand should be a number" ; exit()
     350        return self.__sub__(other)
     351
     352    # define the reverse operation float/int * object
     353    def __rmul__(self,other):
     354        isnum = self.checktwo(other)
     355        if not isnum: print "!! ERROR !! Operand should be a number" ; exit()
     356        return self.__mul__(other)
     357
     358    # define the reverse operation float/int / object
     359    def __rdiv__(self,other):
     360        isnum = self.checktwo(other)
     361        if not isnum: print "!! ERROR !! Operand should be a number" ; exit()
     362        return self.__div__(other)
    286363
    287364    # define the operation ** on one object.
     365    # ... with selective_copy the self object is not modified.
    288366    def __pow__(self,num):
    289         if self.status == "definedplot":
    290             self.status = "retrieved" # to release a warning so that .defineplot() is done before .makeplot()
    291                                       # ... otherwise operated fields will not be displayed
     367        the_clone = self.selective_copy()
    292368        if isinstance(num,int) or isinstance(num,float):
    293369            for i in range(self.nfin):
     
    297373                for y in range(self.nploty):
    298374                 for x in range(self.nplotx):
    299                   obj  = self.request[i][j][t][z][y][x]
     375                  obj  = the_clone.request[i][j][t][z][y][x]
     376                  obj_ref = self.request[i][j][t][z][y][x]
    300377                  if "vector" in self.vargoal[j] + self.filegoal[i]:
    301                       exit() # we do not operate on vectors yet.
     378                      print "!! ERROR !! we do not operate on vectors yet."
     379                      exit()
    302380                  else:
    303                       obj = obj ** num
     381                      obj.field = obj_ref.field ** num
    304382        else:
    305383            print "!! ERROR !! To define a power, either an int or a float is needed." ; exit()
    306         return self
     384        return the_clone
    307385
    308386    # define the operation <<
    309387    # ... e.g. obj2 << obj1
    310388    # ... means: get init for pp object obj2 from another pp object obj1
    311     # ... (this should solve the affectation trap)
     389    # ... (this should solve the affectation trap obj2 = obj1)
    312390    def __lshift__(self,other):
    313391        if other.__class__.__name__ == "pp":
     
    665743                if self.n == 0:
    666744                    self.fig.add_subplot(1,1,1,axisbg=pl.axisbg) # define one subplot (still needed for user-defined font sizes)
    667                     sav = pl.xlabel,pl.ylabel,pl.title,pl.swaplab # save titles and labels
     745                    sav = pl.xlabel,pl.ylabel,pl.xcoeff,pl.ycoeff,pl.title,pl.swaplab # save titles and labels
    668746                else:
    669747                    pl.invert = False ; pl.lstyle = None # don't invert again axis
    670                     pl.xlabel,pl.ylabel,pl.title,pl.swaplab = sav # set saved titles and labels
     748                    # set saved titles and labels
     749                    if self.plotin is None:
     750                        pl.xlabel,pl.ylabel,pl.xcoeff,pl.ycoeff,pl.title,pl.swaplab = sav
     751                    else:
     752                        prev_plot = self.plotin.p[self.n-1]
     753                        pl.xlabel = prev_plot.xlabel
     754                        pl.ylabel = prev_plot.ylabel
     755                        pl.xcoeff = prev_plot.xcoeff
     756                        pl.ycoeff = prev_plot.ycoeff
     757                        pl.title = prev_plot.title
     758                        pl.swaplab = prev_plot.swaplab
    671759            else:
    672760                self.fig.add_subplot(self.subv,self.subh,self.n+1,axisbg=pl.axisbg)
     
    850938        self.swap_axes = False ; self.invert_axes = False
    851939        self.compute = None
    852 
    853     # redefine the + operation. works with objects or numbers.
    854     # -------------------------------
    855     def __add__(self,other):
    856        if isinstance(other,int) or isinstance(other,float):
    857            self.field = self.field + other
    858        elif other.__class__.__name__ == "onerequest":
    859            if self.field.shape != other.field.shape:
    860               print "!! ERROR !! The two objects you want to add do not have the same shape.",self.field.shape,other.field.shape
    861               exit()
    862            else:
    863               self.field = self.field + other.field
    864               if self.file != other.file: self.file = self.file + "_+_" + other.file
    865               if self.var != other.var: self.var = self.var + "_+_" + other.var
    866        else:
    867            print "!! ERROR !! Operation is being made on objects of the wrong type." ; exit()
    868 
    869     # redefine the - operation. works with objects or numbers.
    870     # -------------------------------
    871     def __sub__(self,other):
    872        if isinstance(other,int) or isinstance(other,float):
    873            self.field = self.field - other
    874        elif other.__class__.__name__ == "onerequest":
    875            if self.field.shape != other.field.shape:
    876               print "!! ERROR !! The two objects you want to add do not have the same shape.",self.field.shape,other.field.shape
    877               exit()
    878            else:
    879               self.field = self.field - other.field
    880               if self.file != other.file: self.file = self.file + "_-_" + other.file
    881               if self.var != other.var: self.var = self.var + "_-_" + other.var
    882        else:
    883            print "!! ERROR !! Operation is being made on objects of the wrong type." ; exit()
    884 
    885     # redefine the * operation. works with objects or numbers.
    886     # -------------------------------
    887     def __mul__(self,other):
    888        if isinstance(other,int) or isinstance(other,float):
    889            self.field = self.field * other
    890        elif other.__class__.__name__ == "onerequest":
    891            if self.field.shape != other.field.shape:
    892               print "!! ERROR !! The two objects you want to add do not have the same shape.",self.field.shape,other.field.shape
    893               exit()
    894            else:
    895               self.field = self.field * other.field
    896               if self.file != other.file: self.file = self.file + "_*_" + other.file
    897               if self.var != other.var: self.var = self.var + "_*_" + other.var
    898        else:
    899            print "!! ERROR !! Operation is being made on objects of the wrong type." ; exit()
    900 
    901     # redefine the / operation. works with objects or numbers.
    902     # -------------------------------
    903     def __div__(self,other):
    904        if isinstance(other,int) or isinstance(other,float):
    905            self.field = self.field / other
    906        elif other.__class__.__name__ == "onerequest":
    907            if self.field.shape != other.field.shape:
    908               print "!! ERROR !! The two objects you want to add do not have the same shape.",self.field.shape,other.field.shape
    909               exit()
    910            else:
    911               self.field = self.field / other.field
    912               if self.file != other.file: self.file = self.file + "_/_" + other.file
    913               if self.var != other.var: self.var = self.var + "_/_" + other.var
    914        else:
    915            print "!! ERROR !! Operation is being made on objects of the wrong type." ; exit()
    916 
    917     # redefine the power operation.
    918     # -------------------------------
    919     def __pow__(self,num):
    920        if isinstance(num,int) or isinstance(num,float):
    921            self.field = self.field ** num
    922            self.file = self.file + "_^_"+str(num)
    923            self.var = self.var + "_^_"+str(num)
    924        else:
    925            print "!! ERROR !! To define a power, either an int or a float is needed." ; exit()
    926940
    927941    # open a file. for now it is netcdf. TBD for other formats.
Note: See TracChangeset for help on using the changeset viewer.