diff --git a/dartwrf/dart_nml.py b/dartwrf/dart_nml.py index 11dc4c14bc77c0fef7ef7a58ca3b07cf889923eb..d38f144e035b8a1c4a5cc68c8e569c94ddabd50a 100644 --- a/dartwrf/dart_nml.py +++ b/dartwrf/dart_nml.py @@ -198,7 +198,7 @@ def _get_list_of_localizations(): l_loc_vert_km.append(vert_norm_hgt) # set the other (unused) list to a dummy value - l_loc_vert_scaleheight = [-1,] + l_loc_vert_scaleheight.append(-1) except KeyError: # localization by scale height try: @@ -208,7 +208,7 @@ def _get_list_of_localizations(): l_loc_vert_scaleheight.append(loc_vert_scaleheight) # set the other (unused) list to a dummy value - l_loc_vert_km = [-1,] + l_loc_vert_km.append(-1) except KeyError: @@ -224,38 +224,6 @@ def _get_list_of_localizations(): return l_obstypes, l_loc_horiz_rad, l_loc_vert_km, l_loc_vert_scaleheight -# def _fortran_format(l): - -# # do we have multiples entries? -# # Caution: a string is iterable -# if isinstance(l, list): -# pass -# else: -# l = [l,] - -# # do we have strings as elements? -# if isinstance(l[0], str): - - -# return l - -# def _as_fortran_list(l): -# """Convert parameter list - -# if l contains strings: -# output: "arg1", "arg2", "arg3" -# else -# output 1,2,3 -# """ -# assert isinstance(l, list) - -# if isinstance(l[0], str): -# # contains strings -# l = ['"'+a+'"' for a in l] # add quotation marks - - - - def write_namelist(just_prior_values=False): """Write a DART namelist file ('input.nml') @@ -281,9 +249,11 @@ def write_namelist(just_prior_values=False): nml = read_namelist(cluster.dart_srcdir + "/input.nml") - if len(list_obstypes) > 0: + n_obstypes = len(list_obstypes) + if n_obstypes > 0: # make sure that observations defined in `exp.observations` are assimilated nml['&obs_kind_nml']['assimilate_these_obs_types'] = [list_obstypes] + nml['&obs_kind_nml']['evaluate_these_obs_types'] = [[]] # write localization variables nml['&assim_tools_nml']['special_localization_obs_types'] = [list_obstypes] @@ -293,8 +263,8 @@ def write_namelist(just_prior_values=False): nml['&location_nml']['special_vert_normalization_heights'] = [list_loc_vert_km] nml['&location_nml']['special_vert_normalization_scale_heights'] = [list_loc_vert_scaleheight] - nml['&location_nml']['special_vert_normalization_levels'] = [[-1,]] - nml['&location_nml']['special_vert_normalization_pressures'] = [[-1,]] + nml['&location_nml']['special_vert_normalization_levels'] = [[-1,]*n_obstypes] + nml['&location_nml']['special_vert_normalization_pressures'] = [[-1,]*n_obstypes] # dont compute posterior, just evaluate prior if just_prior_values: diff --git a/dartwrf/obs/obsseq.py b/dartwrf/obs/obsseq.py index c58ec79f61e09a631ed5877daf38563a17ad77b1..49f3bd80498f2a3888014166b294af31cb187d44 100755 --- a/dartwrf/obs/obsseq.py +++ b/dartwrf/obs/obsseq.py @@ -535,6 +535,41 @@ class ObsSeq(object): list_of_obsdict = obs_list_to_dict(obs_list) return list_of_obsdict + def append_obsseq(self, list_of_obsseq): + """Append a list of ObsSeq objects + + Args: + list_of_obsseq (list of ObsSeq()) + + """ + from dartwrf.obs.obskind import obs_kind_nrs # dictionary string => DART internal indices + inverted_obs_kind_nrs = {v: k for k, v in obs_kind_nrs.items()} + + for a in list_of_obsseq: + if not isinstance(a, ObsSeq): + raise ValueError('Input must be of type ObsSeq!') + + # combine data of all inputs + self + list_of_obsseq_df = [self.df,] + list_of_obsseq_df.extend([a.df for a in list_of_obsseq]) + + combi_df = pd.concat(list_of_obsseq_df, + ignore_index=True # we use a new observation index now + ) + + n_obstypes = combi_df.kind.nunique() + list_kinds = combi_df.kind.unique() + + obstypes = [] + for kind in list_kinds: + obstypes.append((kind, inverted_obs_kind_nrs[kind])) + + oso3 = self + oso3.df = combi_df + oso3.obstypes = obstypes + return oso3 + + def to_pandas(self): """Create pd.DataFrame with rows=observations """ diff --git a/tests/obs_seq.T2m+WV73.out b/tests/obs_seq.T2m+WV73.out new file mode 100644 index 0000000000000000000000000000000000000000..d1d71cb457b5b2ce5a04857f13a0c42d49ce4b62 --- /dev/null +++ b/tests/obs_seq.T2m+WV73.out @@ -0,0 +1,73 @@ + obs_sequence + obs_kind_definitions + 2 + 102 SYNOP_TEMPERATURE + 261 MSG_4_SEVIRI_TB + num_copies: 2 num_qc: 1 + num_obs: 4 max_num_obs: 4 + observations + truth + Quality Control + first: 1 last: 2 +OBS 1 +301.509009144877 +301.0021510973083 +0.0 + -1 2 -1 +obdef +loc3d +6.250862521029294 0.7617386402731844 2.0 -1 +kind + 102 + + 46800 148864 + 1.0 +OBS 2 +299.99534143331243 +301.376166801592 +0.0 + -1 3 -1 +obdef +loc3d +6.255199745180597 0.7618054856165454 2.0 -1 +kind + 102 + + 46800 148864 + 1.0 +OBS 3 +252.2826500887255 +251.26893399358806 +0.0 + -1 4 -1 +obdef +loc3d +6.250862521029294 0.7617386402731844 -888888.0 -2 +kind + 261 + visir + 180.00000000000000 45.000000000000000 207.05673522605844 28.897810301100350 + 12 4 21 6 + -888888.00000000000 + 1 + + 46800 148864 + 4.0 +OBS 4 +252.2114425561486 +254.97309329270772 +0.0 + 3 -1 -1 +obdef +loc3d +6.255199745180597 0.7618054856165454 -888888.0 -2 +kind + 261 + visir + 180.00000000000000 45.000000000000000 207.05673522605844 28.897810301100350 + 12 4 21 6 + -888888.00000000000 + 2 + + 46800 148864 + 4.0 diff --git a/tests/obs_seq.T2m.out b/tests/obs_seq.T2m.out new file mode 100644 index 0000000000000000000000000000000000000000..3628d4f3142d431aaa2718fee8ddb83f642d943a --- /dev/null +++ b/tests/obs_seq.T2m.out @@ -0,0 +1,36 @@ + obs_sequence + obs_kind_definitions + 1 + 102 SYNOP_TEMPERATURE + num_copies: 2 num_qc: 1 + num_obs: 2 max_num_obs: 2 + observations + truth + Quality Control + first: 1 last: 2 +OBS 1 +301.509009144877 +301.0021510973083 +0.0 + -1 2 -1 +obdef +loc3d +6.250862521029294 0.7617386402731844 2.0 -1 +kind + 102 + + 46800 148864 + 1.0 +OBS 2 +299.99534143331243 +301.376166801592 +0.0 + 1 -1 -1 +obdef +loc3d +6.255199745180597 0.7618054856165454 2.0 -1 +kind + 102 + + 46800 148864 + 1.0 diff --git a/tests/obs_seq.WV73.out b/tests/obs_seq.WV73.out new file mode 100644 index 0000000000000000000000000000000000000000..5e34f208e30325b9094a058926a279f4b9e9b1f6 --- /dev/null +++ b/tests/obs_seq.WV73.out @@ -0,0 +1,46 @@ + obs_sequence + obs_kind_definitions + 1 + 261 MSG_4_SEVIRI_TB + num_copies: 2 num_qc: 1 + num_obs: 2 max_num_obs: 2 + observations + truth + Quality Control + first: 1 last: 2 +OBS 1 +252.2826500887255 +251.26893399358806 +0.0 + -1 2 -1 +obdef +loc3d +6.250862521029294 0.7617386402731844 -888888.0 -2 +kind + 261 + visir + 180.00000000000000 45.000000000000000 207.05673522605844 28.897810301100350 + 12 4 21 6 + -888888.00000000000 + 1 + + 46800 148864 + 4.0 +OBS 2 +252.2114425561486 +254.97309329270772 +0.0 + 1 -1 -1 +obdef +loc3d +6.255199745180597 0.7618054856165454 -888888.0 -2 +kind + 261 + visir + 180.00000000000000 45.000000000000000 207.05673522605844 28.897810301100350 + 12 4 21 6 + -888888.00000000000 + 2 + + 46800 148864 + 4.0 diff --git a/tests/obs_seq.combi-expected.out b/tests/obs_seq.combi-expected.out new file mode 100644 index 0000000000000000000000000000000000000000..f68ecb37223e6726eaa1534bab29802e78e9e4d8 --- /dev/null +++ b/tests/obs_seq.combi-expected.out @@ -0,0 +1,77 @@ + obs_sequence + obs_kind_definitions + 2 + 102 SYNOP_TEMPERATURE + 261 MSG_4_SEVIRI_TB + num_copies: 2 num_qc: 1 + num_obs: 4 max_num_obs: 4 + observations + truth + Quality Control + first: 1 last: 4 +OBS 1 +301.509009144877 +301.0021510973083 +0.0 + -1 2 -1 +obdef +loc3d +6.250862521029294 0.7617386402731844 2.0 -1 +kind + 102 + + + 46800 148864 + 1.0 +OBS 2 +299.99534143331243 +301.376166801592 +0.0 + -1 3 -1 +obdef +loc3d +6.255199745180597 0.7618054856165454 2.0 -1 +kind + 102 + + + 46800 148864 + 1.0 +OBS 3 +252.2826500887255 +251.26893399358806 +0.0 + -1 4 -1 +obdef +loc3d +6.250862521029294 0.7617386402731844 -888888.0 -2 +kind + 261 + visir + 180.00000000000000 45.000000000000000 207.05673522605844 28.897810301100350 + 12 4 21 6 + -888888.00000000000 + 1 + + + 46800 148864 + 4.0 +OBS 4 +252.2114425561486 +254.97309329270772 +0.0 + 3 -1 -1 +obdef +loc3d +6.255199745180597 0.7618054856165454 -888888.0 -2 +kind + 261 + visir + 180.00000000000000 45.000000000000000 207.05673522605844 28.897810301100350 + 12 4 21 6 + -888888.00000000000 + 2 + + + 46800 148864 + 4.0 \ No newline at end of file diff --git a/tests/test_obsseq.py b/tests/test_obsseq.py index 776946537d028366cfdcce9632b53954c1c1fd67..f2abb6e4bf835f8a6f07b567dc5a95714f6f2e6f 100644 --- a/tests/test_obsseq.py +++ b/tests/test_obsseq.py @@ -52,6 +52,43 @@ def test_superob(): from IPython import embed; embed() +def test_concat_obsseq(): + """Test the concatenation of two obs_seq.out files""" + + + + f1 = './obs_seq.T2m.out' + f2 = './obs_seq.WV73.out' + f_output = './obs_seq.combi.out' + f_expected = './obs_seq.combi-expected.out' + + oso1 = obsseq.ObsSeq(f1) + oso2 = obsseq.ObsSeq(f2) + + # #oso3 = oso1 + # combi_df = pd.concat([oso1.df, oso2.df], + # ignore_index=True # we use a new observation index now + # ) + + # n_obstypes = combi_df.kind.nunique() + # list_kinds = combi_df.kind.unique() + + # obstypes = [] + # for kind in list_kinds: + # obstypes.append((kind, inverted_obs_kind_nrs[kind])) + + # oso3 = oso1 + # oso3.df = combi_df #setattr(oso3, 'df', combi_df) + # oso3.obstypes = obstypes #setattr(oso3, 'obstypes', obstypes) + + oso3 = oso1.append_obsseq([oso2, ]) + oso3.to_dart(f_output) + + import filecmp + assert filecmp.cmp(f_output, f_expected) + + os.remove(f_output) + + if __name__ == '__main__': - test_superob() - pass + test_concat_obsseq() \ No newline at end of file