Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4516268
Trying combining offset with use_actual_channels
orlewis Jul 18, 2023
267400b
A commit
orlewis Jul 31, 2023
5fbcae4
Commit some changes
orlewis Jul 31, 2023
367c588
A push for testing purposes.
orlewis Aug 1, 2023
0693597
Some more changes, bu failing at call to fillchan
orlewis Aug 2, 2023
9160d8f
Strip out the offset channels and use_actual_channels.
orlewis Aug 2, 2023
7f6eb8b
This is an example of a setup which works. I think the Ob % ChanNum =…
orlewis Aug 2, 2023
3b70b72
This is the setup that I think is required but this crashes at line 1…
orlewis Aug 2, 2023
d7281c6
Change output dir to mine (plevens) and remove / at end of output_dir…
PJLevensMO Aug 3, 2023
6c94212
Change path of another file to my own directory due to permission pro…
PJLevensMO Aug 3, 2023
4f4cb4d
remove output_directory line
PJLevensMO Aug 3, 2023
475552c
Change to CallSign in yaml
PJLevensMO Aug 4, 2023
76eda7f
Change to fields in yaml
PJLevensMO Aug 4, 2023
d1dcd48
Changes to lat, lon, and time for ctest
PJLevensMO Aug 4, 2023
fb14ab9
Change level field in ctest yaml
PJLevensMO Aug 7, 2023
1ec327b
Update ob value field in ctest yaml
PJLevensMO Aug 7, 2023
3d968eb
Merge branch 'develop' into feature/map_chans
PJLevensMO Aug 7, 2023
ff5a6b5
Add size_of_varobs_array back to opsinputs_varobswriter_mod.f90 and a…
PJLevensMO Aug 9, 2023
8db38c3
This is a bit messy and may need to be reverted but handy to see what…
orlewis Aug 21, 2023
3474b2d
A por version which has just reintroduced previous options under new …
orlewis Aug 23, 2023
612f81d
All the ctests are now passing.
orlewis Aug 24, 2023
6cf78b2
Change to the logic to work for var channels not compressed.
orlewis Aug 25, 2023
585cdf5
Creating an option to increase the size of the channel array to the s…
orlewis Aug 29, 2023
0f69bcf
Merge branch 'develop' into feature/map_chans
orlewis Aug 29, 2023
604247d
remove some of the write statements
orlewis Sep 15, 2023
ecc201d
Merge branch 'develop' into feature/map_chans
orlewis Sep 19, 2023
6de28db
Some tidy up, removing write statements etc.
orlewis Sep 22, 2023
9c78b00
Merge branch 'feature/map_chans' of https://github.com/MetOffice/opsi…
orlewis Sep 22, 2023
c1d6ab6
Removing outdated comments
orlewis Sep 22, 2023
61daafd
Restore develop versions, nothing should have changed with these files.
orlewis Sep 25, 2023
f0745a1
Adding local variables to handle optional better. Dealing with review…
orlewis Sep 26, 2023
e69c9e5
Remove own drietories and correct typo
orlewis Sep 26, 2023
61c2116
re include emissivity
orlewis Sep 26, 2023
4a7ff45
Missed brackets off if statement
orlewis Sep 26, 2023
178c036
Fix missing brackets for if statements, remove extra variables from t…
orlewis Sep 27, 2023
5ed1762
MCC changes
mikecooke77 Sep 28, 2023
fa689d4
Merge branch 'feature/map_chans' of https://github.com/MetOffice/opsi…
mikecooke77 Sep 28, 2023
c6c03ec
Switch compress_var_channels to be default true
orlewis Sep 28, 2023
f3f53ea
Fix if statement logic
orlewis Sep 28, 2023
be8274c
More changes to the if logic so that the ctests pass.
orlewis Sep 29, 2023
a195cca
Merge branch 'feature/map_chans' of https://github.com/MetOffice/opsi…
orlewis Sep 29, 2023
ca33a65
Remove merge issues
orlewis Sep 29, 2023
7dd1b1a
Return emissivity setting to original.
orlewis Sep 29, 2023
5850350
Merge branch 'feature/map_chans' of https://github.com/MetOffice/opsi…
mikecooke77 Oct 2, 2023
2a88f13
empty commit
orlewis Oct 2, 2023
e4bdc7f
Merge branch 'feature/map_chans' of https://github.com/MetOffice/opsi…
mikecooke77 Oct 3, 2023
dc0419b
Merge branch 'develop' into feature/map_chans
mikecooke77 Oct 4, 2023
0578f73
Another edit to the if statement logic.
orlewis Oct 4, 2023
dd10238
Merge branch 'feature/map_chans' of https://github.com/MetOffice/opsi…
mikecooke77 Oct 9, 2023
4f60601
Improve logic
mikecooke77 Oct 10, 2023
a50c5c1
Merge branch 'develop' into feature/map_chans
orlewis Oct 19, 2023
f31875a
Merge branch 'feature/map_chans_simplify_logic' into feature/map_chans
orlewis Oct 20, 2023
197a18a
Update descriptions for new options.
orlewis Oct 20, 2023
334b696
Change sizeVarObs to sizeOfVarobsArray
orlewis Oct 30, 2023
c6f17ed
Remove the emissivity part from https://rom-saf.eumetsat.int/romsaf_r…
orlewis Nov 1, 2023
fbeb883
Update to use IMDI
orlewis Nov 30, 2023
4d07e90
Merge branch 'develop' into feature/map_chans
orlewis Dec 1, 2023
04fc0b5
Merge branch 'develop' into feature/map_chans
mikecooke77 Dec 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/opsinputs/VarObsWriter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "ioda/ObsVector.h"
#include "oops/base/Variables.h"
#include "oops/mpi/mpi.h"
#include "oops/util/IntSetParser.h"
#include "oops/util/Logger.h"
#include "opsinputs/LocalEnvironment.h"
#include "opsinputs/VarObsWriterParameters.h"
Expand Down Expand Up @@ -70,6 +71,13 @@ VarObsWriter::VarObsWriter(ioda::ObsSpace & obsdb, const Parameters_ & params,
const int fallbackChannels = 0;
// Avoid passing a null pointer to Fortran.
const int *channelsData = channels.empty() ? &fallbackChannels : channels.data();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding a comment here?

// Want to also set up an ordered list of channels numbered for VAR.
std::set<int> varchanset = oops::parseIntSet(parameters_.varChannels.value());
varchannels_.assign(varchanset.begin(), varchanset.end());
conf.set("varChannels", varchannels_);
conf.set("NumVarChannels", sizeof(varchannels_));

if (!opsinputs_varobswriter_create_f90(key_, &conf,
fortranMpiCommunicatorIsValid,
fortranMpiCommunicator,
Expand Down
3 changes: 3 additions & 0 deletions src/opsinputs/VarObsWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

#include <memory>
#include <ostream>
#include <set>
#include <string>
#include <vector>

#include "ioda/ObsDataVector.h"
#include "oops/base/Variables.h"
Expand Down Expand Up @@ -87,6 +89,7 @@ class VarObsWriter : public oops::interface::ObsFilterBase<ufo::ObsTraits>,
oops::Variables extradiagvars_;
std::shared_ptr<ioda::ObsDataVector<int>> flags_;
std::shared_ptr<ioda::ObsDataVector<float>> obsErrors_;
std::vector<int> varchannels_;

VarObsWriterParameters parameters_;
};
Expand Down
22 changes: 13 additions & 9 deletions src/opsinputs/VarObsWriterParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,25 @@ class VarObsWriterParameters : public oops::ObsFilterParametersBase {
/// Update OPS flag to output the varbc predictors
oops::Parameter<bool> outputVarBCPredictors{"output_varbc_predictors", false, this};

/// This contains the offset that needs to be added to the channel number in order to
/// index the output arrays correctly.
oops::Parameter<int> channel_offset{"channel_offset", 0, this};

/// This is the size of the varobs array for output. The default is zero and the size
/// of the array will be used.
/// For atovs, jedi has 20 brightness temperatures but var expects 40.
/// Therefore for atovs brightness_tmperatuere => size_of_varobs_array = 40.
oops::Parameter<int> size_of_varobs_array{"size_of_varobs_array", 0, this};

/// This matches the channel number with the array index. This is useful when
/// there are skipped channels. e.g. channels 5,6,7,9,10,11 are required from a possible 12
/// channels. This would fill a size 12 array with the array indexes matching the channel number
/// [NaN,NaN,NaN,Nan,5,6,7,Nan,9,10,11,NaN].
oops::Parameter<bool> use_actual_channels{"use_actual_channels", false, this};
/// List of channels which are expected for Var. This enables mapping of JOPA
/// channel numbers to VAR numbers. Default is empty and the JOPA channels will be used.
oops::Parameter<std::string> varChannels{"varChannels", "", this};

/// If set to false (default true) this matches the channel number with the array index.
/// This is useful when there are skipped channels. e.g. channels 5,6,7,9,10,11 are
/// required from a possible 12 channels. This would fill a size 12 array with the array
/// indexes matching the channel number [NaN,NaN,NaN,Nan,5,6,7,Nan,9,10,11,NaN].
/// Compressed example could be [2,8,50,100], no missing values between channel numbers.
oops::Parameter<bool> compressVarChannels{"compress_var_channels", true, this};

/// Increase the channel array size to the same size as the varobs array
oops::Parameter<bool> increaseChanArray{"increase_chan_array", false, this};

/// If this list of ufo::variable is defined in the yaml a subset of the flags
/// will be made with just these variables present. This will allow Fortran calls such-as
Expand Down
133 changes: 92 additions & 41 deletions src/opsinputs/opsinputs_fill_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1030,12 +1030,19 @@ end subroutine opsinputs_fill_fillreal
!> of variables with suffixes corresponding to the indices specified in \p Channels.
!> \param[in] JediGroup
!> Group of the JEDI variable used to populate \p Real2.
!> \param[in] compressVarChannels
!> Whether to apply var channel compression (No NaN spaces between channels)
!> \param[in] sizeOfVarobsArray
!> The size of the varobs array which the output data will be stored in.
!> \param[in] varChannels
!> A list of the var channel numbers which the channels will be mapped to.
!>
!> \note This function returns early (without a warning) if the specified JEDI variable is not found.
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
!> are not found.
subroutine opsinputs_fill_fillreal2d_norecords( &
Hdr, OpsVarName, NumObs, Real2, ObsSpace, Channels, JediVarName, JediVarGroup, OffsetChans, useActualChans)
Hdr, OpsVarName, NumObs, Real2, ObsSpace, Channels, JediVarName, &
JediVarGroup, compressVarChannels, sizeOfVarobsArray, varChannels)
implicit none

! Subroutine arguments:
Expand All @@ -1047,8 +1054,10 @@ subroutine opsinputs_fill_fillreal2d_norecords( &
integer(c_int), intent(in) :: Channels(:)
character(len=*), intent(in) :: JediVarName
character(len=*), intent(in) :: JediVarGroup
type(opsinputs_channeloffset), optional, intent(in) :: OffsetChans
logical, optional, intent(in) :: useActualChans
logical, optional, intent(in) :: compressVarChannels
integer(integer64), optional, intent(in) :: sizeOfVarobsArray
integer(c_int), optional, intent(in) :: varChannels(:)


! Local declarations:
real(kind=c_double) :: VarValue(NumObs)
Expand All @@ -1057,52 +1066,77 @@ subroutine opsinputs_fill_fillreal2d_norecords( &
integer :: iChannel
integer :: offset
integer :: numchans
logical :: localUseActualChans
integer :: offsetsize
integer :: arrayindex
logical :: compressChannels

! Body:

MissingDouble = missing_value(0.0_c_double)

compressChannels = .true.
if (present(compressVarChannels)) then
compressChannels = compressVarChannels
end if

JediVarNamesWithChannels = opsinputs_fill_varnames_with_channels(JediVarName, Channels)

!take into account offsetting of 2nd dimension if required
!designed to be used to pack where multiple satellite instruments expected
!e.g. HIRS in ATOVS stream
offset = 0
numchans = size(JediVarNamesWithChannels)
if (present(OffsetChans)) then
offset = OffsetChans % channel_offset
if (OffsetChans % size_of_varobs_array > 0) &
numchans = OffsetChans % size_of_varobs_array
end if

!Setup for channels needing to match array index
localUseActualChans = .false.
if (present(useActualChans)) then
localUseActualChans = useActualChans
numchans = size(JediVarNamesWithChannels)
!sizeOfVarobsArray comes from intitial setting of size_of_varobs_array
! used to define the size of the channel array to fill.
if (present(sizeOfVarobsArray)) then
if (sizeOfVarobsArray > 0) then
numchans = sizeOfVarobsArray
end if
end if

if (obsspace_has(ObsSpace, JediVarGroup, JediVarNamesWithChannels(1))) then
! Allocate OPS data structures
call Ops_Alloc(Hdr, OpsVarName, NumObs, Real2, &
num_levels = int(numchans, kind=integer64))
do iChannel = 1, size(JediVarNamesWithChannels)
! Retrieve data from JEDI
call obsspace_get_db(ObsSpace, JediVarGroup, JediVarNamesWithChannels(iChannel), VarValue)

! Fill the OPS data structures
if (localUseActualChans) then
where (VarValue /= MissingDouble)
Real2(:, Channels(iChannel)) = VarValue
end where
arrayindex = iChannel

! if VAR channels have been assigned then jopa channels will be mapped to these var channels
! Set up the size of the array, if channels are being pushed together an offset between
! the var and jopa channel numbers is added onto the size of the array.
! If not compressed the positions in the array are based on the actual channel number.

if (present(varChannels)) then

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a comment is needed to explain what is happening in this new section.

if (size(varChannels) > 0) then
if (iChannel <= size(varChannels)) then
if (compressChannels) then
offsetsize = abs(varChannels(1) - channels(1))
Comment thread
james-cotton marked this conversation as resolved.
arrayindex = arrayindex + offsetsize
else
arrayindex = varChannels(iChannel)
end if
end if
else
if (.not. compressChannels) then
arrayindex = Channels(iChannel)
end if
end if
else
! Fill the OPS data structures
where (VarValue /= MissingDouble)
Real2(:, iChannel+offset) = VarValue
end where
if (present(sizeOfVarobsArray)) then
if (sizeOfVarobsArray > size(channels)) then
if (.not. compressChannels) then
arrayindex = Channels(iChannel)
end if
end if
end if ! the end
end if
where (VarValue /= MissingDouble)
Real2(:, arrayindex) = VarValue
end where
end do
end if ! Data not present? OPS will produce a warning -- we don't need to duplicate it.

end subroutine opsinputs_fill_fillreal2d_norecords

! ------------------------------------------------------------------------------
Expand Down Expand Up @@ -1223,8 +1257,8 @@ end subroutine opsinputs_fill_fillreal2d_records
!> We rely on warnings printed by the OPS code whenever data needed to output a requested varfield
!> are not found.
subroutine opsinputs_fill_fillreal2d( &
Hdr, OpsVarName, JediToOpsLayoutMapping, Real2, ObsSpace, Channels, VarobsLength, JediVarName, JediVarGroup, OffsetChans, &
useActualChans)
Hdr, OpsVarName, JediToOpsLayoutMapping, Real2, ObsSpace, Channels, &
VarobsLength, JediVarName, JediVarGroup, compressVarChannels, sizeOfVarobsArray, varChannels)
implicit none

! Subroutine arguments:
Expand All @@ -1237,28 +1271,44 @@ subroutine opsinputs_fill_fillreal2d( &
integer(integer64), intent(in) :: VarobsLength
character(len=*), intent(in) :: JediVarName
character(len=*), intent(in) :: JediVarGroup
type(opsinputs_channeloffset), optional, intent(in) :: OffsetChans
logical, optional, intent(in) :: useActualChans
logical, optional, intent(in) :: compressVarChannels
integer(integer64), optional, intent(in) :: sizeOfVarobsArray
integer(c_int), optional, intent(in) :: varChannels(:)

! local variables
logical :: compressChannels
integer(integer64) :: sizeOfVarobsArray_local
integer(c_int), allocatable :: localvarChannels(:)

! Body:

compressChannels = .true.
if (present(compressVarChannels)) then
compressChannels = compressVarChannels
end if

if (present(varChannels)) then
allocate(localvarChannels(size(varChannels)))
localvarChannels = varChannels
end if

sizeOfVarobsArray_local = 0
if (present(sizeOfVarobsArray)) then
sizeOfVarobsArray_local = sizeOfVarobsArray
end if

if (JediToOpsLayoutMapping % ConvertRecordsToMultilevelObs) then
call opsinputs_fill_fillreal2d_records( &
Hdr, OpsVarName, JediToOpsLayoutMapping, Real2, ObsSpace, VarobsLength, JediVarName, JediVarGroup)
else
if (Present(OffsetChans)) then
if (Present(useActualChans)) then
call opsinputs_fill_fillreal2d_norecords( &
Hdr, OpsVarName, JediToOpsLayoutMapping % NumOpsObs, Real2, ObsSpace, Channels, &
JediVarName, JediVarGroup, OffsetChans, useActualChans)
else
call opsinputs_fill_fillreal2d_norecords( &
Hdr, OpsVarName, JediToOpsLayoutMapping % NumOpsObs, Real2, ObsSpace, Channels, &
JediVarName, JediVarGroup, OffsetChans)
end if
if (allocated(localvarChannels)) then
call opsinputs_fill_fillreal2d_norecords( &
Hdr, OpsVarName, JediToOpsLayoutMapping % NumOpsObs, Real2, ObsSpace, Channels, &
JediVarName, JediVarGroup, compressChannels, sizeOfVarobsArray_local, varChannels)
else
call opsinputs_fill_fillreal2d_norecords( &
Hdr, OpsVarName, JediToOpsLayoutMapping % NumOpsObs, Real2, ObsSpace, Channels, &
JediVarName, JediVarGroup)
JediVarName, JediVarGroup, compressChannels, sizeOfVarobsArray_local)
end if
end if

Expand Down Expand Up @@ -2386,6 +2436,7 @@ function opsinputs_fill_varnames_with_channels(VarName, Channels) result(VarName
write (VarNames(ichan),'(A,"_",I0)') VarName, Channels(ichan)
end do
end if

end function opsinputs_fill_varnames_with_channels


Expand Down
Loading
Loading