Loading CHANGELOG +10 −0 Original line number Diff line number Diff line Loading @@ -539,3 +539,13 @@ v2.13 Updates for latest python versions. Improved error checks. v2.14 ----- Plot pixels als polygons in case track information is not present. src/cso/cso_catalogue.py src/cso/cso_plot.py doc/source/history.rst +8 −13 Original line number Diff line number Diff line Loading @@ -122,13 +122,8 @@ A summary of the versions and changes. * | *v2.13* | Minor updates to trap errors and support latest Python versions. To be included ============== Features available in branches, that should be included in master version. * Create map plots as a list of pixels, in case track information is not available. *(E.D.)* * | *v2.14* | Plot pixels als polygons in case track information is not present. To be done Loading Loading @@ -162,7 +157,7 @@ A wishlist of developments. How to create a version tag =========================== Example for tag "v2.13". Example for tag "v2.14". 1. Update file formatting following conventions. Loading @@ -182,17 +177,17 @@ Example for tag "v2.13". c. Change the release tag that will also be imported to the documenation in the `pyproject.toml <../../../pyproject.toml>`_ file:: release = "2.13" release = "2.14" d. Commit and push these changes:: git commit -m 'Defined v2.13' . git commit -m 'Defined v2.14' . git push 4. Tag and push the code to the git repository:: git tag -a 'v2.13' -m 'Tagged v2.13' git push origin v2.13 git tag -a 'v2.14' -m 'Tagged v2.14' git push origin v2.14 pyproject.toml +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "cso" version = "2.13" version = "2.14" authors = [ { name = "Arjo Segers" }, { name = "Lewis Blake" }, Loading src/cso/cso_catalogue.py +131 −47 Original line number Diff line number Diff line Loading @@ -35,6 +35,11 @@ # Extended unit conversions. # Fixed reading of settings for map styles. # # 2025-09, Arjo Segers # Plot pixels als polygons in case track information is not present. # Extended unit conversions. # Fixed string formatting. # ######################################################################## Loading Loading @@ -156,6 +161,30 @@ class CSO_CatalogueBase(utopya.UtopyaRc): # apply factor: values = values * 1e6 # vertical column density: elif conversion == "molec/cm2 -> umol/m2": # apply factor: # molec/cm2 / (molec/mol) umol/mol cm2/m2 values = values / cso_constants.Avog * 1e6 * 1e4 # vertical column density: elif conversion == "molec/cm2 -> 1e15 mlc/cm2": # apply factor: # molec/cm2 values = values / 1e15 # vertical column density: elif conversion == "(molec/cm2)**2 -> 1e15 mlc/cm2": # apply factor: # molec/cm2 values = numpy.sqrt(values) / 1e15 # vertical column density, squared elif conversion == "(molec/cm2)**2 -> umol/m2": # apply factor: # molec/cm2 / (molec/mol) umol/mol cm2/m2 values = numpy.sqrt(values) / cso_constants.Avog * 1e6 * 1e4 # vertical column density: elif conversion == "mol m-2 -> mmol/m2": # apply factor: Loading Loading @@ -383,7 +412,11 @@ class CSO_Catalogue(CSO_CatalogueBase): filename = os.path.join(inputdir, fname) # orbit key: if "orbit" in xlst: orbit = xlst.GetValue(fname, "orbit") else: orbit = "" #endif ## testing ... # if '1200' not in filename : continue Loading Loading @@ -444,23 +477,32 @@ class CSO_Catalogue(CSO_CatalogueBase): # settings for this variable: vkey = "var.%s" % varname # plot type: ptype = self.GetSetting("var.{varname}.type", default="map") ptype = self.GetSetting(f"var.{varname}.type", default="map") # input variable: vname = self.GetSetting("var.{varname}.source", default=varname) vname = self.GetSetting(f"var.{varname}.source", default=varname) # target units: vunits = self.GetSetting("var.{varname}.units", default="None") vunits = self.GetSetting(f"var.{varname}.units", default="None") # long name used in labels: long_name = self.GetSetting("var.{varname}.long_name", default=varname) long_name = self.GetSetting(f"var.{varname}.long_name", default=varname) # track defined in files? on_track = "track_longitude" in orb.ds # switch: if ptype == "map": # style: vmin = eval(self.GetSetting("var.{varname}.vmin", default="None")) vmax = eval(self.GetSetting("var.{varname}.vmax", default="None")) colors = eval(self.GetSetting("var.{varname}.colors", default="None")) vmin = eval(self.GetSetting(f"var.{varname}.vmin", default="None")) vmax = eval(self.GetSetting(f"var.{varname}.vmax", default="None")) colors = eval(self.GetSetting(f"var.{varname}.colors", default="None")) # extract corner grids and values: xx, yy, values, attrs = orb.GetTrack(vname) if on_track: xx, yy, values, attrs = orb.GetTrack(sstate.ds[vname]) else: xx, attrs = orb.GetData( "longitude_bounds" ) yy, attrs = orb.GetData( "latitude_bounds" ) values, attrs = orb.GetData( vname ) #endif # adhoc, some chocho files have nans in lon/lat bound arrays, # these are still present because the scan line has some valid values ... Loading Loading @@ -512,6 +554,7 @@ class CSO_Catalogue(CSO_CatalogueBase): bmp.update(bmp_kwargs) # create map figure: if on_track: fig = cso_plot.QuickPat( values, x=xx, Loading @@ -525,6 +568,21 @@ class CSO_Catalogue(CSO_CatalogueBase): title=title, figsize=figsize, ) else: fig = cso_plot.QuickPoly( values, x=xx, y=yy, vmin=vmin, vmax=vmax, cmap=dict(colors=colors, color_bad=color_nan), bmp=bmp, domain=domain, cbar=dict(label=label), title=title, figsize=figsize, ) #endif # save: fig.Export(figfile) Loading Loading @@ -812,25 +870,35 @@ class CSO_SimCatalogue(CSO_CatalogueBase): else: vfile, vname = "data", vsource # endif # track defined in files? on_track = "track_longitude" in sdata.ds # extract corner grids and values: if vfile == "state": # check ... if vname not in sstate.ds.keys(): logging.error( "variable `%s` not found in state from file: %s" % (vname, statefile) ) logging.error(f"variable '{vname}' not found in state from file: {statefile}") raise Exception # endif # extract corner grids and values: if on_track: xx, yy, values, attrs = sdata.GetTrack(sstate.ds[vname]) else: xx, attrs = sdata.GetData( "longitude_bounds" ) yy, attrs = sdata.GetData( "latitude_bounds" ) values, attrs = sstate.GetData( vname ) #endif elif vfile == "data": # extract corner grids and values from data file: if on_track: xx, yy, values, attrs = sdata.GetTrack(vname) else: xx, attrs = sdata.GetData( "longitude_bounds" ) yy, attrs = sdata.GetData( "latitude_bounds" ) values, attrs = sdata.GetData( vname ) #endtry else: logging.error( 'unsupported type keyword "%s" in source description "%s" for variable "%s"' % (vfile, vsource, varname) f"unsupported type keyword '{vfile}' in source description '{vsource}' for variable '{varname}'" ) raise Exception # endif Loading @@ -849,9 +917,7 @@ class CSO_SimCatalogue(CSO_CatalogueBase): if (len(shp) == 3) and (shp[2] == 1): values = values[:, :, 0] else: logging.error( 'could not squeeze "%s" %s to 2D track' % (vname, str(shp)) ) logging.error(f"could not squeeze '{vname}' {shp} to 2D track") raise Exception # endif # endif Loading @@ -866,7 +932,10 @@ class CSO_SimCatalogue(CSO_CatalogueBase): bmp = dict(countries=True) bmp.update(bmp_kwargs) # info ... logging.info(indent + " plot pattern ...") # create map figure: if on_track: fig = cso_plot.QuickPat( values, x=xx, Loading @@ -880,6 +949,21 @@ class CSO_SimCatalogue(CSO_CatalogueBase): title=title, figsize=figsize, ) else: fig = cso_plot.QuickPoly( values, x=xx, y=yy, vmin=vmin, vmax=vmax, cmap=dict(colors=colors, color_bad=color_nan), bmp=bmp, domain=domain, cbar=dict(label=label), title=title, figsize=figsize, ) #endif # save: fig.Export(figfile) Loading @@ -902,7 +986,7 @@ class CSO_SimCatalogue(CSO_CatalogueBase): # break else: logging.info(indent + " no state file: %s" % statefile) logging.info(f"{indent} no state file: {statefile}") # endif # state file present # next: Loading src/cso/cso_gridded.py +5 −4 Original line number Diff line number Diff line Loading @@ -40,6 +40,9 @@ # 2025-09, Arjo Segers # Updated calculation of temporal means for files with time records. # # 2026-01, Arjo Segers # Fixed timerange setup. # ######################################################################## Loading Loading @@ -593,14 +596,12 @@ class CSO_GriddedAverage(utopya.UtopyaRc): elif tstep in ["day", "daily"]: # start and end of days: rtt1 = pandas.date_range(start=outfile_t1, end=outfile_t2, freq="D")[:-1] rtt2 = pandas.date_range( start=rtt1[0] + pandas.Timedelta(days=1), periods=len(rtt1) ) rtt2 = pandas.date_range(start=rtt1[0] + pandas.Timedelta(days=1), periods=len(rtt1)) # elif tstep in ["hour", "hourly"]: # hours, end is now the same as start ... rtt1 = pandas.date_range(start=outfile_t1, end=outfile_t2, freq="h")[:-1] rtt2 = tt1 rtt2 = rtt1 else: logging.error(f"unsupported output file frequency {tstep}") raise Exception Loading Loading
CHANGELOG +10 −0 Original line number Diff line number Diff line Loading @@ -539,3 +539,13 @@ v2.13 Updates for latest python versions. Improved error checks. v2.14 ----- Plot pixels als polygons in case track information is not present. src/cso/cso_catalogue.py src/cso/cso_plot.py
doc/source/history.rst +8 −13 Original line number Diff line number Diff line Loading @@ -122,13 +122,8 @@ A summary of the versions and changes. * | *v2.13* | Minor updates to trap errors and support latest Python versions. To be included ============== Features available in branches, that should be included in master version. * Create map plots as a list of pixels, in case track information is not available. *(E.D.)* * | *v2.14* | Plot pixels als polygons in case track information is not present. To be done Loading Loading @@ -162,7 +157,7 @@ A wishlist of developments. How to create a version tag =========================== Example for tag "v2.13". Example for tag "v2.14". 1. Update file formatting following conventions. Loading @@ -182,17 +177,17 @@ Example for tag "v2.13". c. Change the release tag that will also be imported to the documenation in the `pyproject.toml <../../../pyproject.toml>`_ file:: release = "2.13" release = "2.14" d. Commit and push these changes:: git commit -m 'Defined v2.13' . git commit -m 'Defined v2.14' . git push 4. Tag and push the code to the git repository:: git tag -a 'v2.13' -m 'Tagged v2.13' git push origin v2.13 git tag -a 'v2.14' -m 'Tagged v2.14' git push origin v2.14
pyproject.toml +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "cso" version = "2.13" version = "2.14" authors = [ { name = "Arjo Segers" }, { name = "Lewis Blake" }, Loading
src/cso/cso_catalogue.py +131 −47 Original line number Diff line number Diff line Loading @@ -35,6 +35,11 @@ # Extended unit conversions. # Fixed reading of settings for map styles. # # 2025-09, Arjo Segers # Plot pixels als polygons in case track information is not present. # Extended unit conversions. # Fixed string formatting. # ######################################################################## Loading Loading @@ -156,6 +161,30 @@ class CSO_CatalogueBase(utopya.UtopyaRc): # apply factor: values = values * 1e6 # vertical column density: elif conversion == "molec/cm2 -> umol/m2": # apply factor: # molec/cm2 / (molec/mol) umol/mol cm2/m2 values = values / cso_constants.Avog * 1e6 * 1e4 # vertical column density: elif conversion == "molec/cm2 -> 1e15 mlc/cm2": # apply factor: # molec/cm2 values = values / 1e15 # vertical column density: elif conversion == "(molec/cm2)**2 -> 1e15 mlc/cm2": # apply factor: # molec/cm2 values = numpy.sqrt(values) / 1e15 # vertical column density, squared elif conversion == "(molec/cm2)**2 -> umol/m2": # apply factor: # molec/cm2 / (molec/mol) umol/mol cm2/m2 values = numpy.sqrt(values) / cso_constants.Avog * 1e6 * 1e4 # vertical column density: elif conversion == "mol m-2 -> mmol/m2": # apply factor: Loading Loading @@ -383,7 +412,11 @@ class CSO_Catalogue(CSO_CatalogueBase): filename = os.path.join(inputdir, fname) # orbit key: if "orbit" in xlst: orbit = xlst.GetValue(fname, "orbit") else: orbit = "" #endif ## testing ... # if '1200' not in filename : continue Loading Loading @@ -444,23 +477,32 @@ class CSO_Catalogue(CSO_CatalogueBase): # settings for this variable: vkey = "var.%s" % varname # plot type: ptype = self.GetSetting("var.{varname}.type", default="map") ptype = self.GetSetting(f"var.{varname}.type", default="map") # input variable: vname = self.GetSetting("var.{varname}.source", default=varname) vname = self.GetSetting(f"var.{varname}.source", default=varname) # target units: vunits = self.GetSetting("var.{varname}.units", default="None") vunits = self.GetSetting(f"var.{varname}.units", default="None") # long name used in labels: long_name = self.GetSetting("var.{varname}.long_name", default=varname) long_name = self.GetSetting(f"var.{varname}.long_name", default=varname) # track defined in files? on_track = "track_longitude" in orb.ds # switch: if ptype == "map": # style: vmin = eval(self.GetSetting("var.{varname}.vmin", default="None")) vmax = eval(self.GetSetting("var.{varname}.vmax", default="None")) colors = eval(self.GetSetting("var.{varname}.colors", default="None")) vmin = eval(self.GetSetting(f"var.{varname}.vmin", default="None")) vmax = eval(self.GetSetting(f"var.{varname}.vmax", default="None")) colors = eval(self.GetSetting(f"var.{varname}.colors", default="None")) # extract corner grids and values: xx, yy, values, attrs = orb.GetTrack(vname) if on_track: xx, yy, values, attrs = orb.GetTrack(sstate.ds[vname]) else: xx, attrs = orb.GetData( "longitude_bounds" ) yy, attrs = orb.GetData( "latitude_bounds" ) values, attrs = orb.GetData( vname ) #endif # adhoc, some chocho files have nans in lon/lat bound arrays, # these are still present because the scan line has some valid values ... Loading Loading @@ -512,6 +554,7 @@ class CSO_Catalogue(CSO_CatalogueBase): bmp.update(bmp_kwargs) # create map figure: if on_track: fig = cso_plot.QuickPat( values, x=xx, Loading @@ -525,6 +568,21 @@ class CSO_Catalogue(CSO_CatalogueBase): title=title, figsize=figsize, ) else: fig = cso_plot.QuickPoly( values, x=xx, y=yy, vmin=vmin, vmax=vmax, cmap=dict(colors=colors, color_bad=color_nan), bmp=bmp, domain=domain, cbar=dict(label=label), title=title, figsize=figsize, ) #endif # save: fig.Export(figfile) Loading Loading @@ -812,25 +870,35 @@ class CSO_SimCatalogue(CSO_CatalogueBase): else: vfile, vname = "data", vsource # endif # track defined in files? on_track = "track_longitude" in sdata.ds # extract corner grids and values: if vfile == "state": # check ... if vname not in sstate.ds.keys(): logging.error( "variable `%s` not found in state from file: %s" % (vname, statefile) ) logging.error(f"variable '{vname}' not found in state from file: {statefile}") raise Exception # endif # extract corner grids and values: if on_track: xx, yy, values, attrs = sdata.GetTrack(sstate.ds[vname]) else: xx, attrs = sdata.GetData( "longitude_bounds" ) yy, attrs = sdata.GetData( "latitude_bounds" ) values, attrs = sstate.GetData( vname ) #endif elif vfile == "data": # extract corner grids and values from data file: if on_track: xx, yy, values, attrs = sdata.GetTrack(vname) else: xx, attrs = sdata.GetData( "longitude_bounds" ) yy, attrs = sdata.GetData( "latitude_bounds" ) values, attrs = sdata.GetData( vname ) #endtry else: logging.error( 'unsupported type keyword "%s" in source description "%s" for variable "%s"' % (vfile, vsource, varname) f"unsupported type keyword '{vfile}' in source description '{vsource}' for variable '{varname}'" ) raise Exception # endif Loading @@ -849,9 +917,7 @@ class CSO_SimCatalogue(CSO_CatalogueBase): if (len(shp) == 3) and (shp[2] == 1): values = values[:, :, 0] else: logging.error( 'could not squeeze "%s" %s to 2D track' % (vname, str(shp)) ) logging.error(f"could not squeeze '{vname}' {shp} to 2D track") raise Exception # endif # endif Loading @@ -866,7 +932,10 @@ class CSO_SimCatalogue(CSO_CatalogueBase): bmp = dict(countries=True) bmp.update(bmp_kwargs) # info ... logging.info(indent + " plot pattern ...") # create map figure: if on_track: fig = cso_plot.QuickPat( values, x=xx, Loading @@ -880,6 +949,21 @@ class CSO_SimCatalogue(CSO_CatalogueBase): title=title, figsize=figsize, ) else: fig = cso_plot.QuickPoly( values, x=xx, y=yy, vmin=vmin, vmax=vmax, cmap=dict(colors=colors, color_bad=color_nan), bmp=bmp, domain=domain, cbar=dict(label=label), title=title, figsize=figsize, ) #endif # save: fig.Export(figfile) Loading @@ -902,7 +986,7 @@ class CSO_SimCatalogue(CSO_CatalogueBase): # break else: logging.info(indent + " no state file: %s" % statefile) logging.info(f"{indent} no state file: {statefile}") # endif # state file present # next: Loading
src/cso/cso_gridded.py +5 −4 Original line number Diff line number Diff line Loading @@ -40,6 +40,9 @@ # 2025-09, Arjo Segers # Updated calculation of temporal means for files with time records. # # 2026-01, Arjo Segers # Fixed timerange setup. # ######################################################################## Loading Loading @@ -593,14 +596,12 @@ class CSO_GriddedAverage(utopya.UtopyaRc): elif tstep in ["day", "daily"]: # start and end of days: rtt1 = pandas.date_range(start=outfile_t1, end=outfile_t2, freq="D")[:-1] rtt2 = pandas.date_range( start=rtt1[0] + pandas.Timedelta(days=1), periods=len(rtt1) ) rtt2 = pandas.date_range(start=rtt1[0] + pandas.Timedelta(days=1), periods=len(rtt1)) # elif tstep in ["hour", "hourly"]: # hours, end is now the same as start ... rtt1 = pandas.date_range(start=outfile_t1, end=outfile_t2, freq="h")[:-1] rtt2 = tt1 rtt2 = rtt1 else: logging.error(f"unsupported output file frequency {tstep}") raise Exception Loading