From nancy at ucar.edu Wed Aug 5 18:25:12 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Wed, 5 Aug 2009 18:25:12 -0600 (MDT) Subject: [Dart-dev] [3985] DART/trunk/time_manager/time_manager_mod.html: Initial documentation for the time manager functions. Message-ID: <200908060025.n760PC2x013725@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090805/c4fd2463/attachment-0001.html -------------- next part -------------- Added: DART/trunk/time_manager/time_manager_mod.html =================================================================== --- DART/trunk/time_manager/time_manager_mod.html (rev 0) +++ DART/trunk/time_manager/time_manager_mod.html 2009-08-06 00:25:12 UTC (rev 3985) @@ -0,0 +1,1031 @@ + +
++Provides a set of routines to manipulate both time and calendars +of various types. +
+Time intervals are stored and defined in terms of integer number +of days and integer seconds. The minimum time resolution is 1 second. +Mathematical operations (e.g. addition, subtraction, multiplication) are +defined on these intervals. Seconds which roll over 86400 (the number +of seconds in a day) are converted into days. +
+Calendars interpret time intervals in terms of years, months, days. +Various calendars commonly in use in the scientific community are +supported. +
+ + + + ++types_mod +utilities_mod ++ + + + + +
use time_manager_mod, only : | +time_type |
operator(+) | |
operator(-) | |
operator(*) | |
operator(/) | |
operator(>) | |
operator(>=) | |
operator(==) | |
operator(/=) | |
operator(<) | |
operator(<=) | |
operator(//) | |
set_time | |
set_time_missing | |
increment_time | |
decrement_time | |
get_time | |
interval_alarm | |
repeat_alarm | |
THIRTY_DAY_MONTHS | |
JULIAN | |
GREGORIAN | |
NOLEAP | |
NO_CALENDAR | |
GREGORIAN_MARS | |
set_calendar_type | |
get_calendar_type | |
get_calendar_string | |
set_date | |
get_date | |
increment_date | |
decrement_date | |
days_in_month | |
leap_year | |
length_of_year | |
days_in_year | |
month_name | |
julian_day | |
time_manager_init | |
print_time | |
print_date | |
write_time | |
read_time | |
interactive_time |
+No namelist at this time. + + + +
+ + + + + + + + ++type(time_type) :: set_time +integer, intent(in) :: seconds +integer, intent(in), optional :: days +
+Fills a time type. If seconds are > 86400, they are converted +into the appropriate number of days. Note that seconds are specified first. +
+seconds | +Number of seconds. If larger than 86400, they are converted + into the appropriate number of days. |
days | +Number of days. Default is 0. |
+type(time_type) :: set_time_missing +
+Set a time type to a missing value. The +resulting time value will cause an error +if used for an arithmetic operation or if get_time() is called. +
++type(time_type) :: increment_time +type(time_type), intent(in) :: time +integer, intent(in) :: seconds +integer, intent(in), optional :: days +
+Adds the specified number of seconds and optionally, days, to the +given time and returns the new time. Increments cannot be negative +(see decrement_time below). +
+time | +time value to be incremented. |
seconds | +number of seconds to add to given time. |
days | +optionally a number of days to add to the given time. |
+type(time_type) :: decrement_time +type(time_type), intent(in) :: time +integer, intent(in) :: seconds +integer, intent(in), optional :: days +
+Subtract the specified number of seconds and optionally, days, to the +given time and returns the new time. Decrements cannot be negative +(see increment_time above). +
+time | +time value to be decremented. |
seconds | +number of seconds to subtract from the given time. |
days | +optionally a number of days to subtract from the given time. |
+logical :: interval_alarm +type(time_type), intent(in) :: time +type(time_type), intent(in) :: time_interval +type(time_type), intent(inout) :: alarm +type(time_type), intent(in) :: alarm_interval +
+ Supports a commonly used type of test on times for models. Given the + current time, and a time for an alarm, determines if this is the closest + time to the alarm time given a time step of time_interval. If this + is the closest time (alarm - time <= time_interval/2), the function + returns true and the alarm is incremented by the alarm_interval. Watch + for problems if the new alarm time is less than time + time_interval. +
+time | +Current time. |
time_interval | +Bin size for determining if alarm time is close enough to now. |
alarm | +When alarm next goes off next. Updated by this routine. |
alarm_interval | +How often alarm goes off. |
+type(time_type) :: repeat_alarm +type(time_type), intent(in) :: time +type(time_type), intent(in) :: alarm_frequency +type(time_type), intent(in) :: alarm_length +
+Repeat_alarm supports an alarm that goes off with alarm_frequency and +lasts for alarm_length. If the nearest occurence of an alarm time +is less than half an alarm_length from the input time, repeat_alarm +is true. For instance, if the alarm_frequency is 1 day, and the +alarm_length is 2 hours, then repeat_alarm is true from time 2300 on +day n to time 0100 on day n + 1 for all n. +
+time | +Current time. |
alarm_frequency | +How often the alarm goes off. |
alarm_length | +How long the alarm is true. |
+integer :: get_calendar_type +
+Returns default calendar type for mapping from time to date. +Calendar types are public integer parameters that define +various calendars. See elsewhere in this file for the list. +
++type(time_type) :: set_date +integer, intent(in) :: year +integer, intent(in) :: month +integer, intent(in) :: day +integer, intent(in), optional :: hours +integer, intent(in), optional :: minutes +integer, intent(in), optional :: seconds +
+Given a date interpreted using the current calendar type, +compute the corresponding time. +P> +
year | +Integer year. |
month | +Integer month number. |
day | +Integer day number. |
hours | +Integer hour. Default is 0. |
minutes | +Integer minutes. Default is 0. |
seconds | +Integer seconds. Default is 0. |
+type(time_type) :: increment_date +type(time_type), intent(in) :: time +integer, intent(in), optional :: years +integer, intent(in), optional :: months +integer, intent(in), optional :: days +integer, intent(in), optional :: hours +integer, intent(in), optional :: minutes +integer, intent(in), optional :: seconds +
+Given a time and some date increment, compute a new time. +The interpretation of the date depends on the currently selected +calendar type. +P> +
time | +Current time. |
year | +Integer years to add. Default is 0. |
month | +Integer months to add. Default is 0. |
day | +Integer days to add. Default is 0. |
hours | +Integer hours to add. Default is 0. |
minutes | +Integer minutes to add. Default is 0. |
seconds | +Integer seconds to add. Default is 0. |
+type(time_type) :: decrement_date +type(time_type), intent(in) :: time +integer, intent(in), optional :: years +integer, intent(in), optional :: months +integer, intent(in), optional :: days +integer, intent(in), optional :: hours +integer, intent(in), optional :: minutes +integer, intent(in), optional :: seconds +
+Given a time and some date decrement, compute a new time. +The interpretation of the date depends on the currently selected +calendar type. +
+time | +Current time. |
year | +Integer years to subtract. Default is 0. |
month | +Integer months to subtract. Default is 0. |
day | +Integer days to subtract. Default is 0. |
hours | +Integer hours to subtract. Default is 0. |
minutes | +Integer minutes to subtract. Default is 0. |
seconds | +Integer seconds to subtract. Default is 0. |
+integer :: days_in_month +type(time_type), intent(in) :: time +
+Given a time, determine the month based on the currently +selected calendar type and return the +numbers of days in that month. +
+time | +Current time. |
+logical :: leap_year +type(time_type),intent(in) :: time +
+Given a time, determine if the current year is a leap +year in the currently selected calendar type. +
+time | +Current time. |
+integer :: length_of_year +
+For the currently selected calendar type, return the +number of days in a year if that value is fixed (e.g. there are +not leap years). For other calendar types, see +days_in_year() which takes a time +argument to determine the current year. +
++integer :: days_in_year +type(time_type), intent(in) :: time +
+Given a time, determine the year based on the currently +selected calendar type and return the +numbers of days in that year. +
+time | +Current time. |
+character(len=9) :: month_name +integer, intent(in) :: n +
+Return a character string containing the month name corresponding +to the given month number. +
+n | +Month number. Must be between 1 and 12, inclusive. |
+integer :: julian_day +integer, intent(in) :: year +integer, intent(in) :: month +integer, intent(in) :: day +
+Given a date in year/month/day format, +compute the day number from the beginning of the year. +The currently selected calendar type must be GREGORIAN. +
+year | +Year number in the Gregorian calendar. |
month | +Month number in the Gregorian calendar. |
day | +Day of month in the Gregorian calendar. |
+type(time_type) :: read_time +integer, intent(in) :: file_unit +character(len=*), intent(in), optional :: form +integer, intent(out), optional :: ios_out +
+Read a time from the given file unit number. The unit must already +be open. The default format is ascii/formatted. If an error is +encountered and ios_out is specified, the error status will be returned +to the caller; otherwise the error is fatal. +
+file_unit | +Integer file unit number of an already open file. |
form | +Format to read the time. Options are 'formatted' + or 'unformatted'. Default is 'formatted'. |
ios_out | +On error, if specified, the error status code is returned here. + If not specified, an error calls the standard error_handler and + exits. |
+type(time_type), intent(in) :: time +integer, intent(out) :: seconds +integer, intent(out), optional :: days +
+Returns days and seconds ( < 86400 ) corresponding to a time. +If the optional 'days' argument is not given, the days are converted +to seconds and the total time is returned as seconds. +Note that seconds preceeds days in the argument list. +
+time | +Time to convert into seconds and days. |
seconds | +If days is specified, number of seconds in the current day. + Otherwise, total number of seconds in time. |
days | +If specified, number of days in time. |
+integer, intent(in) :: mytype + or +character(len=*), intent(in) :: calstring +
+Selects the current calendar type, for converting between time +and year/month/day. The argument can either be one of the predefined +calendar integer parameter types (see elsewhere in this file for +the list of types), or a string which matches the name of the +integer parameters. The string interface is especially suitable for +namelist use. +
+mytype | +Integer parameter to select the calendar type. |
calstring | +Character string to select the calendar type. + Valid strings match the names of the integer parameters. |
+character(len=*), intent(out) :: mystring +
+Return the character string corresponding to the +currently selected calendar type. +
+mystring | +Character string corresponding to the current calendar type. |
+type(time_type), intent(in) :: time +integer, intent(out) :: year +integer, intent(out) :: month +integer, intent(out) :: day +integer, intent(out) :: hour +integer, intent(out) :: minute +integer, intent(out) :: second +
+Given a time, compute the corresponding date given the +currently selected calendar type. +
+time | +Input time. |
year | +Corresponding calendar year. |
month | +Corresponding calendar month. |
day | +Corresponding calendar day. |
hour | +Corresponding hour. |
minute | +Corresponding minute. |
second | +Corresponding second. |
+
+Initializes any internal data needed by the time manager code. +Does not need to be called before using any of the time +manager routines; it will be called internally before executing +any of the other routines. +
++type(time_type), intent(in) :: time +character(len=*), intent(in), optional :: str +integer, intent(in), optional :: iunit + +
+Print the time as days and seconds. If the optional str argument +is specified, print that string as a label. If iunit is specified, +write output to that unit; otherwise write to standard output/terminal. +
+time | +Time to be printed as days/seconds. |
str | +String label to print before days/seconds. Default: 'TIME: '. |
iunit | +Unit number to write output on. Default is standard output/terminal + (unit 6). |
+type(time_type), intent(in) :: time +character(len=*), intent(in), optional :: str +integer, intent(in), optional :: iunit + +
+Print the time as year/month/day/hour/minute/second, as computed +from the currently selected calendar type. +If the optional str argument +is specified, print that string as a label. If iunit is specified, +write output to that unit; otherwise write to standard output/terminal. +
+time | +Time to be printed as a calendar date/time. |
str | +String label to print before date. Default: 'DATE: '. |
iunit | +Unit number to write output on. Default is standard output/terminal + (unit 6). |
+integer, intent(in) :: file_unit +type(time_type), intent(in) :: time +character(len=*), intent(in), optional :: form +integer, intent(out), optional :: ios +
+Write a time to an already open file unit. The optional 'form' +argument controls whether it is formatted or unformatted. +On error, the optional 'ios' argument returns the error code; otherwise +a fatal error is triggered. +
+file_unit | +Integer unit number for an already open file. |
time | +Time to write to the file. |
form | +String format specifier; either 'unformatted' or 'formatted'. + Defaults to 'formatted'. |
ios | +If specified, on error the i/o status error code is returned here. + Otherwise, the standard error handler is called and the + program exits. |
+type(time_type), intent(inout) :: time +
+Prompt the user for a time as a calendar date, based on the +currently selected calendar type. Writes prompt to standard output +and reads from standard input. +
+time | +Time type to be returned. |
+type time_type + private + integer :: seconds + integer :: days +end type time_type +
+This type is used to define a time interval. +
+ + + + + + + ++ integer :: NO_CALENDAR + integer :: GREGORIAN + integer :: GREGORIAN_MARS + integer :: JULIAN + integer :: THIRTY_DAY_MONTHS + integer :: NOLEAP +
+The public integer parameters which define different calendar types. +The same names defined as strings can be used to set the calendar type. +
+ + + + + + ++ operator(+) + operator(-) + operator(*) + operator(/) + operator(>) + operator(>=) + operator(==) + operator(/=) + operator(<) + operator(<=) + operator(//) +
+Arithmetic operations are defined for time types, so expressions like +
+t3 = t1 + t2 ++can be constructed. To use these operators, they must be listed +on the module use statement in the form specified above. + +
+Multiplication is one time and one scalar. +
++Division with a single slash is integer, and returns the largest +integer for which time1 >= time2 * n. Division with a double slash +returns a double precision quotient of the two times. +
+ + + + + + No namelist is currently defined for the time manager code.
+
+
+
+
+
+
+
+
+
Routine | Message | Comment |
---|---|---|
+ | + | + |
+none +
+ + + + + + ++none +
+ + + + + + ++none +
+ + + +Contact: | Jeff Anderson, Tim Hoar |
use schedule_mod, only : | +schedule_type |
set_regular_schedule | |
get_time_from_schedule | |
get_schedule_length |
+Namelist +&schedule_mod_nml +may be read from file input.nml. +
+ + + + + + ++type(schedule_type), intent(out) :: schedule +
+Uses the namelist information to compute and fill a +schedule_type variable. +
+schedule | +Fills this derived type with the information needed to + generate a series of regularly spaced time windows. |
+type(time_type), intent(out) :: mytime + or +real(digits12), intent(out) :: mytime +type(schedule_type), intent(in) :: schedule +integer, intent(in) :: iepoch +integer, intent(in), optional :: edge +
+Returns either the leading or trailing time for the specified +bin/epoch number for the given schedule. The time can be returned in one +of two formats, depending on the variable type specified for the +first argument: either a DART derived time_type, or a real of kind +digits12 (defined in the types_mod). +
+mytime | +Return value with the leading or trailing edge time for the + requested bin. There are two supported return formats, either as + a standard DART time_type, or as a real value which will contain + the number of days plus any fraction. |
schedule | +Schedule type to extract information from. |
iepoch | +The bin number, or epoch number, to return a time for. + Unless edge is specified and requests the ending time, the time + returned is the starting time for this bin. |
edge | +If specified, and if edge is larger than 1, the trailing edge time + of the bin is returned. Any other value, or if this argument is + not specified, returns the leading edge time of the bin. |
+integer :: get_schedule_length +type(schedule_type), intent(in) :: schedule +
+Return the total number of intervals/bins/epochs defined by +this schedule. +
+schedule | +Return number of time intervals in this schedule. |
+type schedule_type + private + integer :: num_bins + integer :: current_bin + logical :: last_bin + integer :: calendar + character(len=32) :: calendarstring + type(time_type) :: binwidth + type(time_type) :: bininterval + type(time_type), pointer :: binstart( :) => NULL() + type(time_type), pointer :: binend( :) => NULL() + real(digits12), pointer :: epoch_start(:) => NULL() + real(digits12), pointer :: epoch_end( :) => NULL() +end type schedule_type +
+This type is used to define a schedule. +
+ + + + + + +We adhere to the F90 standard of starting a namelist with an ampersand + '&' and terminating with a slash '/'. +
+ namelist / schedule_mod_nml / + first_bin_start, first_bin_end, last_bin_end, & + bin_interval_days, bin_interval_seconds, & + max_num_bins, calendar, print_table +
+Controls various aspects of filter. The inflation control variables are all +dimensioned 2, the first value being for the prior inflation and the second +being for the posterior inflation. + +
+This namelist is read in a file called input.nml +
+Contents | +Type | +Description |
---|---|---|
first_bin_start | +integer, dimension(6) | +Date/time specification for starting time + of first bin. + Default: 2008, 9, 7, 0, 0, 0 |
first_bin_end | +integer, dimension(6) | +Date/time specification for ending time + of first bin. Sets the bin width. + Default: 2008, 9, 7, 2, 0, 0 |
last_bin_end | +integer, dimension(6) | +Date/time specification for ending time + of last bin. Sets the length of the overall + time of the schedule. + Default: 2008, 9, 11, 0, 0, 0 |
bin_interval_days | +integer | +Sets the time between bins. Must be larger or + equal to the bin width. + Default: 0 |
bin_interval_seconds | +integer | +Sets the time between bins. Must be larger or + equal to the bin width. + Default: 21600 |
max_num_bins | +integer | +Upper limit on the number of bins. + Default: 1000 |
calendar | +character(len=32) | +String calendar type. Valid types are listed + in the +time_manager_mod file. + Default: "Gregorian" |
print_table | +logical | +If .TRUE., print out information about the schedule + each time set_regular_schedule() is called. + Default: .FALSE. |
Routine | Message | Comment |
---|---|---|
+ | + | + |
+none +
+ + + + + + ++Setting the schedule from the namelist values means you can +only have a single schedule +object in the entire program. We also need a subroutine to initialize +a schedule type by giving explicit arguments. +
+ + + + + + ++none +
+ + + +Contact: | Jeff Anderson, Tim Hoar |
Revision: | $Revision$ |
Source: | $URL$ |
Change Date: | $Date$ |
Change history: | try "svn log" or "svn diff" |
+Provides some commonly used mathematical constants, and a set of +Fortran integer and real kinds, to be used to select the right +variable size (e.g. 4 bytes, 8 bytes) to match the rest of the +DART interfaces. (DART does not depend on compiler flags to +set precision, but explicitly specifies a kind for each variable +in the public interfaces.) +
+ +
+ + + + ++none ++ + + + + +
use types_mod, only : | +i4 |
i8 | |
r4 | |
r8 | |
c4 | |
c8 | |
digits12 | |
PI | |
DEG2RAD | |
RAD2DEG | |
SECPERDAY | |
MISSING_R4 | |
MISSING_R8 | |
MISSING_I | |
MISSING_DATA | |
metadatalength | |
obstypelength | |
t_kelvin | |
es_alpha | |
es_beta | |
es_gamma | |
gas_constant_v | |
gas_constant | |
L_over_Rv | |
ps0 | |
earth_radius | |
gravity |
+No namelist is used by this module. +
+ + + + + + ++integer, parameter :: i4 +integer, parameter :: i8 +integer, parameter :: r4 +integer, parameter :: r8 +integer, parameter :: c4 +integer, parameter :: c8 +integer, parameter :: digits12 +
+These kinds are used when declaring variables, like: +
+real(r8) :: myvariable +integer(i4) :: shortint ++All DART public interfaces use types on the real values to +ensure they are consistent across various compilers and +compile-time options. The digits12 is generally only used +for reals which require extra precision. +
+Some models are able to run with single precision real values, +which saves both memory when executing and file space when +writing and reading restart files. To accomplish this, the +users edit this file, redefine r8 to equal r4, and then rebuild +all of DART. +
+ + + + + ++real(KIND=R8), parameter :: PI +real(KIND=R8), parameter :: DEG2RAD +real(KIND=R8), parameter :: RAD2DEG +real(KIND=R8), parameter :: SECPERDAY +
+Some commonly used math constants, defined here for convenience. +
+ + + + ++real(KIND=R4), parameter :: MISSING_R4 +real(KIND=R8), parameter :: MISSING_R8 +integer, parameter :: MISSING_I +integer, parameter :: MISSING_DATA +
+Numeric constants used in the DART code when a numeric +value is required, but the data is invalid or missing. +These are typically defined as negative and a series +of 8's, so they are distinctive when scanning a list of values. +
+ + + + + ++integer, parameter :: metadatalength +integer, parameter :: obstypelength +
+Some common string limits used system-wide by DART code. +The obstypelength is limited by the Fortran-imposed maximum +number of characters in a parameter; the metadatalength was +selected to be long enough to allow descriptive names but +short enough to keep printing to less than a single line. +
+ + + + + ++real(KIND=R8), parameter :: t_kevin +real(KIND=R8), parameter :: es_alpha +real(KIND=R8), parameter :: es_beta +real(KIND=R8), parameter :: es_gamma +real(KIND=R8), parameter :: gas_constant_v +real(KIND=R8), parameter :: gas_constant +real(KIND=R8), parameter :: L_over_Rv +real(KIND=R8), parameter :: ps0 +real(KIND=R8), parameter :: earth_radius +real(KIND=R8), parameter :: gravity +
+A set of geophysical constants, which could be +argued do not belong in a DART-supplied file since +they are quite probably specific to a model or a +particular forward operator. +
+Best case would be if we could engineer the code so +these constants were provided by the model and then +used when compiling the forward operator files. +But given that Fortran use statements +cannot be circular, this poses a problem. +Perhaps we could work out how the obs_def code could +define these constants and then they could be used +by the model code. +For now, they are defined here but it is up to the +model and obs_def code writers whether to use these or not. +
+ + + + + + + + +Routine | Message | Comment |
---|---|---|
+ | + | + |
+none +
+ + + + + + ++none +
+ + + + + + ++none +
+ + + +Contact: | Jeff Anderson, Tim Hoar |
Revision: | $Revision$ |
Source: | $URL$ |
Change Date: | $Date$ |
Change history: | try "svn log" or "svn diff" |
GPS Radio Occultation data is being returned from a series of satellites as part of the -Cosmic +COSMIC project. The programs in this directory help to extract the data from the distribution files and put them into @@ -80,16 +82,24 @@
Data from -Cosmic +COSMIC is available by signing up on the data access web page. It is delivered in netCDF file format. +The files we use as input to these conversion programs are +the Level 2 data, Atmospheric Profiles (filenames include +the string 'atmPrf').
+Currently each vertical profile is stored in a separate file, +and there are between 1000-2000 profiles/day, so converting a day's +worth of observations involves downloading many individual files. +There are plans in place to bundle these profiles together in +a tar file to make it easier to download the raw data.
@@ -99,26 +109,176 @@+Optional namelist interface + &convert_cosmic_gps_nml +may be read from file input.nml. +
++The work directory contains several scripts, including one which downloads +the raw data files a day at a time (cosmic_download.csh), and one +which executes the conversion program (convert_script.csh). These +scripts make 6 hour files by default, but have options for other +times. The input files are downloaded a day at a time. Be aware +that each profile is stored in a separate netcdf file, and there +are between 1000-2000 files/day, so the download process can be +lengthy. You probably want to download as a separate preprocess step +and do not use the options to automatically delete the input files. +Keep the files around until you are sure you are satisified with the +output files and then delete them by hand. +
++The conversion executable, convert_cosmic_gps_cdf, reads the namelist +from the file 'input.nml', but also reads an analysis time from the +terminal or the standard input unit. This makes it simpler to convert +multiple files without editing the namelist. The program prompts for +the time string with the required time format, +yyyy-mm-dd_hh:mm:ss .
- + + ++types_mod +time_manager_mod +utilities_mod +location_mod +obs_sequence_mod +obs_def_mod +obs_def_gps_mod +obs_kind_mod +netcdf ++ + +
We adhere to the F90 standard of starting a namelist with an ampersand + '&' and terminating with a slash '/'. +
+ namelist / convert_cosmic_gps_nml / + obs_levels, local_operator, obs_window, & + ray_ds, ray_htop, gpsro_netcdf_file, & + gpsro_netcdf_filelist, gpsro_out_file +
This namelist is read in a file called input.nml +
+Contents | +Type | +Description |
---|---|---|
obs_levels | +integer(200) | +A series of heights, in kilometers, where observations + from this profile should be interpolated. (Note that + the other distances and heights in the namelist are + specified in meters.) The values should be listed in + increasing height order. + Default: none |
local_operator | +logical | +If .true., compute the observation using a method + which assumes all effects occur at the tangent point. + If .false., integrate along the tangent line and do + ray-path reconstruction. + Default: .true. |
obs_window | +real(r8) | +Accept and convert observations if they are within + plus or minus this number of hours from the analysis + time (which is read as an input from the terminal or + the standard input unit). + Default: 12.0 |
ray_ds | +real(r8) | +For the non-local operator only, the delta stepsize, + in meters, to use for the along-path integration in + each direction out from the tangent point. + Default: 5000.0 |
ray_htop | +real(r8) | +For the non-local operator only, stop the integration + when one of the endpoints of the next integration step + goes above this height. Specified in meters. + Default: 15000.0 |
gpsro_netcdf_file | +character(len=128) | +The input filename when converting a single profile. + Only one of the 2 filenames can have a valid value, + so to use the single filename set the list name + ('gpsro_netcdf_filelist') to the empty string (''). + Default: 'cosmic_gps_input.nc' |
gpsro_netcdf_filelist | +character(len=128) | +To convert a series of profiles in a single execution + create a text file which contains each input file, + in ascii, one filename per line. Set this item to + the name of that file, and set 'gpsro_netcdf_file' to + the empty string (''). + Default: 'cosmic_gps_input_list' |
gpsro_out_file | +character(len=128) | +The output file to be created. Note that to be + compatible with earlier versions of this program, if + this file already exists it will be read in and the + new data will be inserted into that file. + Default: 'obs_seq.gpsro' |
overwrite_time | +logical | +This item is NOT in the standard namelist, but code + exists in the program to support the functionality + if the source is edited and this variable is added + to the namelist. If set to + .true., the output file will be created with all + observations marked with the specified analysis time + instead of the actual observation collection time. + This is generally not what you want, but might be + useful if you are binning observations by time to do + thinning or super-ob'ing data. + Default: .false. |
+
+ + ++Some COSMIC files seem to have internal times which differ from the +times encoded in the filenames by as much as 2-3 minutes. If it is +important to get all the observations within a particular time window +files with filenames from a few minutes before and after the window +should be converted. +Times really outside the window can be excluded either by setting +the 'obs_window' namelist variable, or can be trimmed later with the +obs_sequence_tool.
- + Modified: DART/trunk/observations/gps/work/convert_script.csh =================================================================== --- DART/trunk/observations/gps/work/convert_script.csh 2009-08-10 19:13:07 UTC (rev 3996) +++ DART/trunk/observations/gps/work/convert_script.csh 2009-08-10 21:33:27 UTC (rev 3997) @@ -3,20 +3,26 @@ # Main script: # generate multiple days of gps observations # -# calls the cosmic_to_obsseq script with a date, the working -# directory location, and whether to download the data automatically -# from the cosmic web site (downloading data requires signing up -# for a username/password to access the site, and then setting -# the username and password here before running this script.) +# calls the cosmic_to_obsseq script with 4 args: # +# - the date in YYYYMMDD format +# - the working directory location +# - whether to download the data automatically from the cosmic web site +# (downloading data requires signing up for a username/password to +# access the site, and then setting the username and password here +# before running this script.) set to no if the data has already been +# downloaded separately before now. +# - whether to delete the data automatically from the local disk after the +# conversion is done. +# setenv cosmic_user xxx setenv cosmic_pw yyy -./cosmic_to_obsseq.csh 20061101 .. yes -./cosmic_to_obsseq.csh 20061102 .. yes -./cosmic_to_obsseq.csh 20061103 .. yes -./cosmic_to_obsseq.csh 20061104 .. yes -./cosmic_to_obsseq.csh 20061105 .. yes -./cosmic_to_obsseq.csh 20061106 .. yes -./cosmic_to_obsseq.csh 20061107 .. yes +./cosmic_to_obsseq.csh 20061101 .. no no +./cosmic_to_obsseq.csh 20061102 .. no no +./cosmic_to_obsseq.csh 20061103 .. no no +./cosmic_to_obsseq.csh 20061104 .. no no +./cosmic_to_obsseq.csh 20061105 .. no no +./cosmic_to_obsseq.csh 20061106 .. no no +./cosmic_to_obsseq.csh 20061107 .. no no Added: DART/trunk/observations/gps/work/cosmic_download.csh =================================================================== --- DART/trunk/observations/gps/work/cosmic_download.csh (rev 0) +++ DART/trunk/observations/gps/work/cosmic_download.csh 2009-08-10 21:33:27 UTC (rev 3997) @@ -0,0 +1,153 @@ +#!/bin/csh +######################################################################## +# +# cosmic_download.csh - script that downloads COSMIC observations. +# then you can run cosmic_to_obsseq.csh with a third argument of +# 'no' so it does not re-download the same files. +# +# requires 2 args: +# $1 - analysis date (yyyymmdd format) +# $2 - base observation directory +# +# and update the 3 env settings at the top to match your system. +# +# created May 2009, nancy collins ncar/cisl +# converted from cosmic_to_obsseq.csh +# updated Aug 2009, nancy collins ncar/cisl +# +# from the cosmic web site about the use of 'wget' to download +# the many files needed to do this process: +# ------- +# Hints for using wget for fetching CDAAC files from CDAAC: +# +# Here is one recipe for fetching all cosmic real time atmPrf files for one day: +# +# wget -nd -np -r -l 10 -w 2 --http-user=xxxx --http-passwd=xxxx http://cosmic-io.cosmic.ucar.edu/cdaac/login/cosmicrt/level2/atmPrf/2009.007/ +# +# The option -np (no parents) is important. Without it, all manner of +# files from throughout the site will be loaded, I think due to the +# links back to the main page which are everywhere. +# +# The option -r (recursive fetch) is necessary unless there is just +# one file you want to fetch. +# +# The option -l 10 (limit of recursive depth to 10 levels) is necessary +# in order to get around the default 5 level depth. +# +# The option -nd dumps all fetched files into your current directory. +# Otherwise a directory hierarchy will be created: +# cosmic-io.cosmic.ucar.edu/cdaac/login/cosmic/level2/atmPrf/2006.207 +# +# The option -w 2 tells wget to wait two seconds between each file fetch +# so as to have pity on our poor web server. +# ------- +# +######################################################################## + +# should only have to set the DART_DIR and the rest should be in the +# right place relative to it. +setenv DART_DIR /home/user/dart +setenv cosmic_user xxx +setenv cosmic_pw yyy + +setenv DART_WORK_DIR ${DART_DIR}/observations/gps/work +setenv CONV_PROG convert_cosmic_gps_cdf +setenv DATE_PROG advance_time + +set chatty=yes +set downld=yes + +set datea = ${1} # target date, YYYYMMDD +set datadir = ${2} # where to process the files + +set assim_freq = 6 # hours, sets centers of windows. +set download_window = 3 # window half-width (some users choose 2 hours) +set gps_repository_path = 'http://cosmic-io.cosmic.ucar.edu/cdaac/login' +set wget_cmd = 'wget -q -nd -np -r -l 10 -w 1' + +# i've done this wrong enough times and wasted a lot of download time, +# so do a bunch of bullet-proofing here before going on. + +# verify the dirs all exist, the input.nml is in place. +if ( ! -d ${DART_WORK_DIR} ) then + echo 'work directory not found: ' ${DART_WORK_DIR} + exit +endif + +echo 'current dir is ' `pwd` +if ( `pwd` != ${DART_WORK_DIR} ) then + echo 'if not already there, changing directory to work dir.' + cd ${DART_WORK_DIR} + echo 'current dir now ' `pwd` +endif + +if ( ! -d ${datadir} ) then + echo 'data processing directory not found: ' ${datadir} + echo 'creating now.' + mkdir ${datadir} + ls -ld ${datadir} +endif + +if ( ! -e ${datadir}/${DATE_PROG} ) then + echo 'data processing directory does not contain the time converter' + echo 'copying from work dir to data proc dir' + echo `pwd`/${DATE_PROG} '->' ${datadir}/${DATE_PROG} + cp -f ./${DATE_PROG} ${datadir} +else + echo 'using time conversion program already found in data proc dir' +endif + +echo 'changing dir to data proc directory' +cd ${datadir} +echo 'current dir now ' `pwd` + + if ( ! $?cosmic_user || ! $?cosmic_pw ) then + echo "You must setenv cosmic_user to your username for the cosmic web site" + echo "and setenv cosmic_pw to your password. (or export cosmic_user=val for" + echo "ksh/bash users) then rerun this script. " + exit -1 + endif + +if ( $chatty == 'yes' ) then + echo 'starting raw file download at' `date` +endif + +set get = "${wget_cmd} --http-user=${cosmic_user} --http-passwd=${cosmic_pw}" + +set yyyy = `echo $datea | cut -b1-4` + +if ( ! -d ${datea} ) then + echo 'year/month/day directory not found: ' ${datea} + echo 'creating now.' + mkdir ${datea} +endif + +cd ${datea} + +echo $datea +set jyyyydd = `echo $datea 0 -j | ../${DATE_PROG}` +echo $jyyyydd +@ mday = $jyyyydd[2] + 1000 ; set mday = `echo $mday | cut -b2-4` +${get} ${gps_repository_path}/cosmic/level2/atmPrf/${yyyy}.${mday}/ +rm -f *.html *.txt +${get} ${gps_repository_path}/champ/level2/atmPrf/${yyyy}.${mday}/ +rm -f *.html *.txt + +set jyyyydd = `echo $datea 24 -j | ../${DATE_PROG}` +@ mday = $jyyyydd[2] + 1000 ; set mday = `echo $mday | cut -b2-4` +${get} ${gps_repository_path}/cosmic/level2/atmPrf/${yyyy}.${mday}/ +rm -f *.html *.txt +${get} ${gps_repository_path}/champ/level2/atmPrf/${yyyy}.${mday}/ +rm -f *.html *.txt + +if ( $chatty == 'yes' ) then + # the ls arg list line gets too long in some cases + echo `/bin/ls | grep _nc | wc -l` 'raw files' + echo 'all raw files download at ' `date` +endif + +cd .. + +exit 0 + + Property changes on: DART/trunk/observations/gps/work/cosmic_download.csh ___________________________________________________________________ Name: svn:executable + * Modified: DART/trunk/observations/gps/work/cosmic_to_obsseq.csh =================================================================== @@ Diff output truncated at 40000 characters. @@ From nancy at ucar.edu Mon Aug 10 16:25:58 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Mon, 10 Aug 2009 16:25:58 -0600 (MDT) Subject: [Dart-dev] [3998] DART/trunk/utilities/utilities_mod.html: Added missing doc for recently added subroutine. Message-ID: <200908102225.n7AMPwAl010439@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090810/01a43a16/attachment.html -------------- next part -------------- Modified: DART/trunk/utilities/utilities_mod.html =================================================================== --- DART/trunk/utilities/utilities_mod.html 2009-08-10 21:33:27 UTC (rev 3997) +++ DART/trunk/utilities/utilities_mod.html 2009-08-10 22:25:57 UTC (rev 3998) @@ -107,6 +107,7 @@+ character(len=*), intent(in) :: listname + integer, intent(in) :: index + character(len=128) :: get_next_filename +
+Returns the specified line of a text file, given a filename and a line number. +It returns an empty string when the line number is larger than the +number of lines in a file. +
++Intended as an easy way to process a list of files. Use a command +like 'ls > out' to +create a file containing the list, in order, of files to be processed. +Then call this function with an increasing index number until the return +value is empty. +
+var | +An ascii string, up to 128 characters long, containing the + contents of line index of the input file. |
listname | +The filename to open and read lines from. |
index | +Integer line number, starting at 1. If larger than the + number of lines in the file, the empty string '' will be returned. |
Contact: | Jeff Anderson |
Revision: | $Revision$ |
Source: | $URL$ |
Change Date: | $Date$ |
Change history: | try "svn log" or "svn diff" |
Utility program to alter the data timestamp in a DART restart file, -to add or remove a model-advance time, to convert from ascii to binary +to add or remove a model-advance time, to convert from ASCII to binary or back, and to either split or combine ensemble restarts into one or multiple files.
@@ -93,16 +85,28 @@-Optional namelist interface +Namelist interface &restart_file_tool_nml -may be read from file input.nml. +must be read from file input.nml.
++ASCII restart files are portable across different hardware architectures +(these days, most notably between IBM PowerX chip-based systems and anything +else including all Intel/AMD systems). +However, they are larger in size, and can lose precision +when converting from binary to ASCII and back. Binary restart files can +be moved even between incompatible systems by using the 'swabrestart' utility +found in the $DART/utilities directory. See the extensive comment section +at the top of that file for an explanation of the details of moving binary +files between incompatible systems. +
+ - +types_mod time_manager_mod @@ -113,19 +117,6 @@ mpi_utilities_mod- - - - -
-
- -- - - - -
Contact: | Jeff Anderson |
Revision: | $Revision$ |
Source: | $URL$ |
Change Date: | $Date$ |
Change history: | try "svn log" or "svn diff" |
types_mod @@ -119,12 +119,12 @@ -
+
NAMELIST
We adhere to the F90 standard of starting a namelist with an ampersand '&' and terminating with a slash '/'.
- namelist / restart_file_tool / + namelist / restart_file_tool_nml / input_file_name, output_file_name, ens_size, single_restart_file_in, single_restart_file_out, write_binary_restart_files, overwrite_data_time, new_data_days, new_data_secs, input_is_model_advance_file, output_is_model_advance_file, @@ -136,7 +136,6 @@Discussion
The namelist sets the behavior of this tool. -
This namelist is read in a file called input.nml
@@ -240,7 +239,7 @@ -
+
FILES
- inputfile (filter_restart)
- restart_file_tool.nml @@ -252,7 +251,7 @@ -
+
REFERENCES
@@ -310,7 +309,7 @@ -
+
KNOWN BUGS
@@ -320,7 +319,7 @@ -
+
FUTURE PLANS
Discussion
From nancy at ucar.edu Tue Aug 25 13:16:14 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Tue, 25 Aug 2009 13:16:14 -0600 (MDT) Subject: [Dart-dev] [4007] DART/trunk/models/coamps/templates/EXAMPLE.input.nml: the COAMPS model no longer requires changes to the obs_kind file, Message-ID: <200908251916.n7PJGEPj025226@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090825/055e7999/attachment.html -------------- next part -------------- Modified: DART/trunk/models/coamps/templates/EXAMPLE.input.nml =================================================================== --- DART/trunk/models/coamps/templates/EXAMPLE.input.nml 2009-08-25 17:59:25 UTC (rev 4006) +++ DART/trunk/models/coamps/templates/EXAMPLE.input.nml 2009-08-25 19:16:11 UTC (rev 4007) @@ -80,7 +80,7 @@ write_binary_obs_sequence = .false. / &preprocess_nml - input_obs_kind_mod_file = '../../../obs_kind/DEFAULT_coamps_obs_kind_mod.F90', + input_obs_kind_mod_file = '../../../obs_kind/DEFAULT_obs_kind_mod.F90', output_obs_kind_mod_file = '../../../obs_kind/obs_kind_mod.f90', input_obs_def_mod_file = '../../../obs_def/DEFAULT_obs_def_mod.F90', output_obs_def_mod_file = '../../../obs_def/obs_def_mod.f90', From nancy at ucar.edu Tue Aug 25 15:18:03 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Tue, 25 Aug 2009 15:18:03 -0600 (MDT) Subject: [Dart-dev] [4008] DART/trunk/models/wrf/model_mod.f90: Allow the radar obs_def to ask for KIND_POWER_WEIGHTED_FALL_SPEED to be Message-ID: <200908252118.n7PLI3fv012118@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090825/3b92039b/attachment.html -------------- next part -------------- Modified: DART/trunk/models/wrf/model_mod.f90 =================================================================== --- DART/trunk/models/wrf/model_mod.f90 2009-08-25 19:16:11 UTC (rev 4007) +++ DART/trunk/models/wrf/model_mod.f90 2009-08-25 21:18:02 UTC (rev 4008) @@ -54,7 +54,7 @@ KIND_ICE_NUMBER_CONCENTRATION, KIND_GEOPOTENTIAL_HEIGHT, & KIND_POTENTIAL_TEMPERATURE, KIND_SOIL_MOISTURE, & KIND_VORTEX_LAT, KIND_VORTEX_LON, & - KIND_RADAR_REFLECTIVITY, & + KIND_RADAR_REFLECTIVITY, KIND_POWER_WEIGHTED_FALL_SPEED,& KIND_VORTEX_PMIN, KIND_VORTEX_WMAX, & get_raw_obs_kind_index, get_num_raw_obs_kinds, & get_raw_obs_kind_name @@ -6016,7 +6016,9 @@ ! way to interpolate it even if it is not in the state vector. if this ! is not allowed it will error exit instead of returning with an invalid istatus ! to indicate to the caller that the interpolation failed. +! ditto for power weighted fall speed. in_state_vector(KIND_RADAR_REFLECTIVITY) = .true. +in_state_vector(KIND_POWER_WEIGHTED_FALL_SPEED) = .true. ! FIXME: i was going to suggest nuking this routine all together because it makes ! the default behavior be to exit with an error when requesting to interpolate an From nancy at ucar.edu Tue Aug 25 16:22:57 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Tue, 25 Aug 2009 16:22:57 -0600 (MDT) Subject: [Dart-dev] [4009] DART/trunk/models/POP/matlab/Check_ud.m: checks the conversion of the pop_to_dart.f90 program Message-ID: <200908252222.n7PMMvWw006910@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090825/e155e52d/attachment.html -------------- next part -------------- Added: DART/trunk/models/POP/matlab/Check_ud.m =================================================================== --- DART/trunk/models/POP/matlab/Check_ud.m (rev 0) +++ DART/trunk/models/POP/matlab/Check_ud.m 2009-08-25 22:22:56 UTC (rev 4009) @@ -0,0 +1,100 @@ +function [dart pop] = Check_ud(dartfile,popfile) +% Check_ud : check the conversion of a POP restart to a DART state vector. +% dartfile = 'assim_model_state_ud'; +% popfile = 'pop.r.nc' +% x = Check_ud(dartfile,popfile); +% +% +% dartfile = '/fs/image/home/thoar/SVN/DART/models/POP/work/assim_model_state_ud'; +% popfile = '/fs/image/home/thoar/SVN/DART/models/POP/work/cx3.dart.001.pop.r.0002-01-01-00000.nc'; +% [dart pop] = Check_ud(dartfile,popfile); +% + +% Read the original POP file values. +% The nc_varget() function returns the variables with the fastest +% varying dimension on the right. This is opposite to the Fortran +% convention of the fastest varying dimension on the left ... so +% one of the variables must be permuted in order to be compared. + +pop.S = nc_varget(popfile, 'SALT_CUR'); +pop.T = nc_varget(popfile, 'TEMP_CUR'); +pop.U = nc_varget(popfile, 'UVEL_CUR'); +pop.V = nc_varget(popfile, 'VVEL_CUR'); +pop.PSURF = nc_varget(popfile, 'PSURF_CUR'); + +[nz ny nx] = size(pop.U); +fprintf('vert dimension size is %d\n',nz) +fprintf('N-S dimension size is %d\n',ny) +fprintf('E-W dimension size is %d\n',nx) + +modelsize = nz*ny*nx; + +% filesize = S,T,U,V * (nx*ny*nz) + SSH * (nx*ny) +storage = 8; +size2d = nx*ny; +size3d = nx*ny*nz; +n2ditems = 1*size2d; +n3ditems = 4*size3d; +rec1size = 4+(4+4)+4; % time stamps ... +rec2size = 4+(n3ditems*storage + n2ditems*storage)+4; + +fsize = rec1size + rec2size; +disp(sprintf('with a modelsize of %d the file size should be %d bytes', ... + modelsize,fsize)) + +% Open and read timetag for state +fid = fopen(dartfile,'rb','ieee-le'); +trec1 = fread(fid,1,'int32'); +seconds = fread(fid,1,'int32'); +days = fread(fid,1,'int32'); +trecN = fread(fid,1,'int32'); + +if (trec1 ~= trecN) + error('first record mismatch') +end + +% Successively read state vector variables. +rec1 = fread(fid, 1, 'int32'); +dart.S = get_3D_permuted(fid, [nx ny nz], 'float64'); +dart.T = get_3D_permuted(fid, [nx ny nz], 'float64'); +dart.U = get_3D_permuted(fid, [nx ny nz], 'float64'); +dart.V = get_3D_permuted(fid, [nx ny nz], 'float64'); +dart.SSH = get_2D_permuted(fid, [nx ny ], 'float64'); +recN = fread(fid, 1, 'int32'); +fclose(fid); + +fprintf(' shape of DART variables is %d \n',size(dart.S)) + +% The POP restart file has PSURF ... DART drags around SSH +% SSH = psurf/980.6; + +dart.PSURF = dart.SSH * 980.6; + +if (rec1 ~= recN) + error('second record mismatch') +end + +dart.dartfile = dartfile; +dart.seconds = seconds; +dart.days = days; + +% Find the range of the mismatch + +Sdiff = pop.S - dart.S; [min( Sdiff(:)) max( Sdiff(:))] +Tdiff = pop.T - dart.T; [min( Tdiff(:)) max( Tdiff(:))] +Udiff = pop.U - dart.U; [min( Udiff(:)) max( Udiff(:))] +Vdiff = pop.V - dart.V; [min( Vdiff(:)) max( Vdiff(:))] +PSURFdiff = pop.PSURF - dart.PSURF; [min(PSURFdiff(:)) max(PSURFdiff(:))] + + +function C = get_3D_permuted(fid, shape, typestr) +datasize = prod(shape); +A = fread(fid, prod(shape), typestr); +B = reshape(A, shape); +C = permute(B, [3 2 1]); + +function C = get_2D_permuted(fid, shape, typestr) +datasize = prod(shape); +A = fread(fid, prod(shape), typestr); +B = reshape(A, shape); +C = permute(B, [2 1]); Property changes on: DART/trunk/models/POP/matlab/Check_ud.m ___________________________________________________________________ Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Revision Author HeadURL Id Name: svn:eol-style + native From nancy at ucar.edu Tue Aug 25 16:54:27 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Tue, 25 Aug 2009 16:54:27 -0600 (MDT) Subject: [Dart-dev] [4010] DART/trunk/perfect_model_obs/perfect_model_obs.f90: Important bug fix: correct the standard deviation passed into Message-ID: <200908252254.n7PMsR9N001446@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090825/da19fbfa/attachment.html -------------- next part -------------- Modified: DART/trunk/perfect_model_obs/perfect_model_obs.f90 =================================================================== --- DART/trunk/perfect_model_obs/perfect_model_obs.f90 2009-08-25 22:22:56 UTC (rev 4009) +++ DART/trunk/perfect_model_obs/perfect_model_obs.f90 2009-08-25 22:54:27 UTC (rev 4010) @@ -350,17 +350,8 @@ ! If observation is not being evaluated or assimilated, skip it ! Ends up setting a 1000 qc field so observation is not used again. if(istatus == 0 .and. (assimilate_this_ob .or. evaluate_this_ob)) then - ! DEBUG: try this out to see if it's useful. if the incoming error - ! variance is negative, add no noise to the values, but do switch the - ! sign on the error so the file is useful in subsequent runs. - errvar = get_obs_def_error_variance(obs_def) - if (errvar > 0.0_r8) then - obs_value(1) = random_gaussian(random_seq, true_obs(1), errvar) - else - obs_value(1) = true_obs(1) - call set_obs_def_error_variance(obs_def, -errvar) - call set_obs_def(obs, obs_def) - endif + obs_value(1) = random_gaussian(random_seq, true_obs(1), & + sqrt(get_obs_def_error_variance(obs_def))) ! Set qc to 0 if none existed before if(cnum_qc == 0) then From nancy at ucar.edu Tue Aug 25 17:04:35 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Tue, 25 Aug 2009 17:04:35 -0600 (MDT) Subject: [Dart-dev] [4011] DART/trunk: GUI presentation of fundamental assimilation concepts Message-ID: <200908252304.n7PN4Z4k006613@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090825/07a8a1fd/attachment-0001.html -------------- next part -------------- Added: DART/trunk/DART_LAB/matlab/advance_oned.m =================================================================== --- DART/trunk/DART_LAB/matlab/advance_oned.m (rev 0) +++ DART/trunk/DART_LAB/matlab/advance_oned.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,25 @@ +function x_new = advance_oned(x, alpha) + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +%
+% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +x_new = x + comp_dt(x, alpha); +end + +%--------------------------------------------------- + +% Internal function comp_dt +function dx = comp_dt(x, alpha) + +% Compute the time tendency; alpha controls nonlinearity +dx = x + alpha .* x .* abs(x); + +end Property changes on: DART/trunk/DART_LAB/matlab/advance_oned.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/comp_cov_factor.m =================================================================== --- DART/trunk/DART_LAB/matlab/comp_cov_factor.m (rev 0) +++ DART/trunk/DART_LAB/matlab/comp_cov_factor.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,26 @@ +function cov_factor = comp_cov_factor(z_in, c) +% Gaspari Cohn cutoff, z_in is the distance while c is the cutoff + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +z = abs(z_in); + +if( z >= c*2.0) + cov_factor = 0; +elseif( z <= c ) + r = z / c; + cov_factor = ((( -0.25*r +0.5)*r +0.625)*r -5.0/3.0)*r^2 + 1.0; +else + r = z / c; + cov_factor = ((((r/12 -0.5)*r +0.625)*r +5.0/3.0)*r -5.0)*r + 4.0 - 2.0 / (3.0 * r); +end + Property changes on: DART/trunk/DART_LAB/matlab/comp_cov_factor.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/g_prod_plot.m =================================================================== --- DART/trunk/DART_LAB/matlab/g_prod_plot.m (rev 0) +++ DART/trunk/DART_LAB/matlab/g_prod_plot.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,107 @@ +function [prior_mean, prior_sd, obs_mean, obs_err_sd, is_err] = g_prod_plot(h) +% Updates the plot of the prior and observation gaussians + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Successful return as defaul t +is_err = false; + +% Default failed returns for other quantities +prior_mean = 0; prior_sd = -1; +obs_mean = 0; obs_err_sd = -1; + +h_prior_mean = get(h.edit1); +prior_mean = str2double(h_prior_mean.String); +% The mean must be a number +if(isnan(prior_mean)) + error_banner(h, 'Prior Mean must be a number'); + is_err = true; + return +end + +h_prior_sd = get(h.edit2); +prior_sd = str2double(h_prior_sd.String); + +% Prior sd must be a number +if(isnan(prior_sd)) + error_banner(h, 'Prior SD must be a postive number'); + is_err = true; + return +end + +% Prior sd must also be positive +if(prior_sd <= 0) + error_banner(h, 'Prior SD must be positive') + is_err = true; + return +end + +hold off +prior_handle = plot_gaussian(prior_mean, prior_sd, 1); +set(prior_handle, 'Color', [0 0.73 0], 'LineWidth', 2); +hold on + +h_obs_mean = get(h.edit3); +obs_mean = str2double(h_obs_mean.String); + +% Obs value must be a number +if(isnan(obs_mean)) + error_banner(h, 'Obs value must be a number'); + is_err = true; + return +end + +h_obs_err_sd = get(h.edit4); +obs_err_sd = str2double(h_obs_err_sd.String); + +% Obs error sd must be a positive number +if(isnan(obs_err_sd)) + error_banner(h, 'Obs Error SD must be a positive number'); + is_err = true; + return +end + +if(obs_err_sd <= 0) + error_banner(h, 'Obs Error SD must be positive'); + is_err = true; + return +end + +obs_handle = plot_gaussian(obs_mean, obs_err_sd, 1); +set(obs_handle, 'Color', 'r', 'LineStyle', '--', 'LineWidth', 2); + +% Put on a legend +legend('Prior', 'Obs. Likelihood'); + +end + +%--------------------------------------------------------- + +% Internal function to write error banner +function error_banner(h, message) + + hold off + x= [1 2]; + plot(x, 'Visible', 'off') + h_fig = get(h.figure1); + x_limits = get(h_fig.CurrentAxes, 'Xlim'); + y_limits = get(h_fig.CurrentAxes, 'Ylim'); + text(x_limits(1) * 7/8 + x_limits(2) / 8, mean(y_limits), ... + message, 'fontsize', 16, 'Color', 'r'); + + % While we're at it, clear out the values for posterior, too + set(h.text7, 'String', 'Posterior Mean = '); + set(h.text8, 'String', 'Posterior SD = '); + set(h.text9, 'String', 'Weight = '); + return; + +end Property changes on: DART/trunk/DART_LAB/matlab/g_prod_plot.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/gaussian_product.fig =================================================================== (Binary files differ) Property changes on: DART/trunk/DART_LAB/matlab/gaussian_product.fig ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + application/octet-stream Added: DART/trunk/DART_LAB/matlab/gaussian_product.m =================================================================== --- DART/trunk/DART_LAB/matlab/gaussian_product.m (rev 0) +++ DART/trunk/DART_LAB/matlab/gaussian_product.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,214 @@ +function varargout = gaussian_product(varargin) +% GAUSSIAN_PRODUCT demonstrates the product of two gaussian distributions. +% +% This is fundamental to ensemble data assimilation. Change the +% parameters of the gaussian for the Prior (green) and the Observation +% (red) and click on 'Plot Posterior'. +% +% The product of the two gaussians is a gaussian - in this case, +% the 'Posterior'. If the parameters of the two gaussians are known, +% the parameters of the resulting gaussian can be calculated. +% +% See also: oned_model, oned_ensemble, twod_ensemble, run_lorenz_63, +% run_lorenz_96 + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Last Modified by GUIDE v2.5 21-Mar-2009 22:11:31 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @gaussian_product_OpeningFcn, ... + 'gui_OutputFcn', @gaussian_product_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before gaussian_product is made visible. +function gaussian_product_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to gaussian_product (see VARARGIN) + +help gaussian_product + +% Choose default command line output for gaussian_product +handles.output = hObject; + +% Update handles structure +guidata(hObject, handles); + +% Plot the initial prior and observation likelihood pdf's +h = guihandles; +g_prod_plot(h); + +% UIWAIT makes gaussian_product wait for user response (see UIRESUME) +% uiwait(handles.figure1); + + +% --- Outputs from this function are returned to the command line. +function varargout = gaussian_product_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure +varargout{1} = handles.output; + + + +function edit1_Callback(hObject, eventdata, handles) +% hObject handle to edit1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit1 as text +% str2double(get(hObject,'String')) returns contents of edit1 as a double + +g_prod_plot(handles); + + +% --- Executes during object creation, after setting all properties. +function edit1_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function edit2_Callback(hObject, eventdata, handles) +% hObject handle to edit2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit2 as text +% str2double(get(hObject,'String')) returns contents of edit2 as a double + +g_prod_plot(handles); + + +% --- Executes during object creation, after setting all properties. +function edit2_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit3_Callback(hObject, eventdata, handles) +% hObject handle to edit3 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit3 as text +% str2double(get(hObject,'String')) returns contents of edit3 as a double + +g_prod_plot(handles); + + +% --- Executes during object creation, after setting all properties. +function edit3_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit3 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit4_Callback(hObject, eventdata, handles) +% hObject handle to edit4 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit4 as text +% str2double(get(hObject,'String')) returns contents of edit4 as a double + +g_prod_plot(handles); + + +% --- Executes during object creation, after setting all properties. +function edit4_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit4 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes on button press in pushbutton1. +function pushbutton1_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Need to replot prior and obs, then compute posterior and plot +[prior_mean, prior_sd, obs_mean, obs_err_sd, is_err] = g_prod_plot(handles); + +% If there is an error, don't try to do posterior computation +% But do zero out the posterior text values +if(is_err) return; + set(handles.text7, 'String', strcat('Posterior Mean = ')); + set(handles.text8, 'String', strcat('Posterior SD = ')); + set(handles.text9, 'String', strcat('Weight = ')); +end + +% Compute the posterior mean, sd and weight +[post_mean, post_sd, weight] = ... + product_of_gaussians(prior_mean, prior_sd, obs_mean, obs_err_sd); +post_handle = plot_gaussian(post_mean, post_sd, 1); +set(post_handle, 'Color', 'b', 'LineWidth', 2); + +% Print values +set(handles.text7, 'String', ['Posterior Mean = ', num2str(post_mean)]); +set(handles.text8, 'String', ['Posterior SD = ', num2str(post_sd)]); + +% Also plot the weighted posterior as dashed +post_handle = plot_gaussian(post_mean, post_sd, weight); +set(post_handle, 'Color', 'b', 'Linestyle', '--'); +set(handles.text9, 'String', ['Weight = ', num2str(weight)]); + +legend('Prior', 'Obs. Likelihood', 'Posterior', 'Weighted Posterior'); + + Property changes on: DART/trunk/DART_LAB/matlab/gaussian_product.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/get_ens_rank.m =================================================================== --- DART/trunk/DART_LAB/matlab/get_ens_rank.m (rev 0) +++ DART/trunk/DART_LAB/matlab/get_ens_rank.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,25 @@ +function [rank] = get_ens_rank(ens, x) + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +s_ens = sort(ens); + +for i = 1 : size(ens, 2) + if(x < s_ens(1, i)) + rank = i; + return; + end +end + +rank = size(ens, 2) + 1; + +end Property changes on: DART/trunk/DART_LAB/matlab/get_ens_rank.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/get_state_increments.m =================================================================== --- DART/trunk/DART_LAB/matlab/get_state_increments.m (rev 0) +++ DART/trunk/DART_LAB/matlab/get_state_increments.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,21 @@ +function [state_incs] = get_state_increments(state_ens, obs_ens, obs_incs) +% Computes state increments given observation increments and +% the state and obs prior ensembles + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Compute state variance and covariance +covar = cov(state_ens, obs_ens); + + +state_incs = obs_incs * covar(1, 2) / covar(2, 2); + Property changes on: DART/trunk/DART_LAB/matlab/get_state_increments.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/lorenz_63_adv_1step.m =================================================================== --- DART/trunk/DART_LAB/matlab/lorenz_63_adv_1step.m (rev 0) +++ DART/trunk/DART_LAB/matlab/lorenz_63_adv_1step.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,51 @@ +function[x_new, time_new] = lorenz_63_adv_1step(x, time) +% Does a single time step advance for lorenz convective 3 variable model +% using two step runge-kutta time step +% +% x is the 3-vector state, time is the 2-vector days and seconds time + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2007, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +global DELTAT + +% Set the fraction for the rk-2 time step +fract = 1; + +% Compute the first intermediate step +dx = comp_dt(x); +x1 = x + fract * DELTAT * dx; + +% Compute the second intermediate step +dx = comp_dt(x1); +x2 = x1 + fract * DELTAT * dx; + +% New value for x is average of original value and second intermediate +x_new = (x + x2) / 2; + +% Update the time ; Non-dimensional single unit for development +time_new = time + 1; + +end + + +function[dt] = comp_dt(x) + +global SIGMA +global R +global B + +dt(1) = SIGMA * (x(2) - x(1)); +dt(2) = -1 * x(1)*x(3) + R*x(1) - x(2); +dt(3) = x(1)*x(2) - B*x(3); + +end + Property changes on: DART/trunk/DART_LAB/matlab/lorenz_63_adv_1step.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/lorenz_63_static_init_model.m =================================================================== --- DART/trunk/DART_LAB/matlab/lorenz_63_static_init_model.m (rev 0) +++ DART/trunk/DART_LAB/matlab/lorenz_63_static_init_model.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,39 @@ +% Initializes class data for L63, sets up global storage +% and reads in control data from input file + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Lorenz-63 model parameters +global SIGMA +global R +global B +global DELTAT +global TIME_STEP_DAYS +global TIME_STEP_SECONDS + +% Set default values for the model parameters +SIGMA = 10; +R = 28; +B = 8/3; +DELTAT = 0.01; +TIME_STEP_DAYS = 0; +TIMES_STEP_SECONDS = 0; + + +% Lorenz-63 fixed model parameters +global MODEL_SIZE + +MODEL_SIZE = 3; + +global STATE_LOC + +STATE_LOC = (0:2) / 3; Property changes on: DART/trunk/DART_LAB/matlab/lorenz_63_static_init_model.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/lorenz_96_adv_1step.m =================================================================== --- DART/trunk/DART_LAB/matlab/lorenz_96_adv_1step.m (rev 0) +++ DART/trunk/DART_LAB/matlab/lorenz_96_adv_1step.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,66 @@ +function[x_new, time_new] = lorenz_96_adv_1step(x, time) +% Does a single time step advance for lorenz_96 40-variable model using four step runge-kutta time step +% +% x is the 40-vector state, time is the 2-vector days and seconds time + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +global DELTA_T + +% Compute first intermediate step +dx = comp_dt(x); +x1 = DELTA_T * dx; +inter = x + x1 / 2; + +% Compute second intermediate step +dx = comp_dt(inter); +x2 = DELTA_T * dx; +inter = x + x2 / 2; + +% Compute third intermediate step +dx = comp_dt(inter); +x3 = DELTA_T * dx; +inter = x + x3; + +% Compute fourth intermediate step +dx = comp_dt(inter); +x4 = DELTA_T * dx; + +% Compute new value for x +x_new = x + x1/6 + x2/3 + x3/3 + x4/6; + +% Increment time step +time_new = time + 1; + + +end + +%------------------------------------------------------------------------------ + +function[dt] = comp_dt(x) + +global FORCING +global MODEL_SIZE + +for j = 1:MODEL_SIZE + jp1 = j + 1; + if(jp1 > MODEL_SIZE) jp1 = 1; end + jm2 = j - 2; + if(jm2 < 1) jm2 = MODEL_SIZE + jm2; end + jm1 = j - 1; + if(jm1 < 1) jm1 = MODEL_SIZE; end + + dt(j) = (x(jp1) - x(jm2)) * x(jm1) - x(j) + FORCING; +end + +end + Property changes on: DART/trunk/DART_LAB/matlab/lorenz_96_adv_1step.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/lorenz_96_static_init_model.m =================================================================== --- DART/trunk/DART_LAB/matlab/lorenz_96_static_init_model.m (rev 0) +++ DART/trunk/DART_LAB/matlab/lorenz_96_static_init_model.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,35 @@ +% Initializes class data for L96, sets up global storage +% and reads in control data from input file + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Lorenz-96 model parameters +global FORCING +global DELTA_T +global TIME_STEP_DAYS +global TIME_STEP_SECONDS + +% Set default values for the model parameters +FORCING = 8; +DELTA_T = 0.05; +TIME_STEP_DAYS = 0; +TIMES_STEP_SECONDS = 0; + + +% Lorenz-96 fixed model parameters +global MODEL_SIZE + +MODEL_SIZE = 40; + +global STATE_LOC + +STATE_LOC = (0:MODEL_SIZE - 1) / MODEL_SIZE; Property changes on: DART/trunk/DART_LAB/matlab/lorenz_96_static_init_model.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/obs_increment_eakf.m =================================================================== --- DART/trunk/DART_LAB/matlab/obs_increment_eakf.m (rev 0) +++ DART/trunk/DART_LAB/matlab/obs_increment_eakf.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,58 @@ +function [obs_increments, err] = obs_increment_eakf(ensemble, observation, obs_error_var) +% Computes increments for an ensemble adjustment filter + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Set error return to default successful +err = 0; + +% Compute prior ensemble mean and variance +prior_mean = mean(ensemble); +prior_var = var(ensemble); + +% If both prior and observation error variance are return error +if(prior_var <= 0 && obs_error_var <= 0) + err = 1; + return; +end + +% Compute the posterior mean and variance +% If prior variance is 0, posterior mean is prior_mean and variance is 0 +if(prior_var == 0) + post_mean = prior_mean; + post_var = 0; +elseif(obs_error_var == 0) +% If obs_error_var is 0, posterior mean is observation and variance is 0 + post_mean = observation; + post_var = 0; +else +% Use product of gaussians + % Compute the posterior variance + post_var = 1 / (1 / prior_var + 1 / obs_error_var); + + % Compute posterior mean + post_mean = post_var * (prior_mean / prior_var + observation / obs_error_var); +end + + +% Shift the prior ensemble to have the posterior mean +updated_ensemble = ensemble - prior_mean + post_mean; + +% Contract the ensemble to have the posterior_variance +var_ratio = post_var / prior_var; +updated_ensemble = sqrt(var_ratio) * (updated_ensemble - post_mean) + post_mean; + +% Compute the increments +obs_increments = updated_ensemble - ensemble; + + + Property changes on: DART/trunk/DART_LAB/matlab/obs_increment_eakf.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/obs_increment_enkf.m =================================================================== --- DART/trunk/DART_LAB/matlab/obs_increment_enkf.m (rev 0) +++ DART/trunk/DART_LAB/matlab/obs_increment_enkf.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,74 @@ +function [obs_increments, err] = obs_increment_eakf(ensemble, observation, obs_error_var) +% Computes increments for an ensemble Kalman filter with perturbed obs mean correction. + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Set error return to default successful +err = 0; + +% Compute prior ensemble mean and variance +prior_mean = mean(ensemble); +prior_var = var(ensemble); + +% If both prior and observation error variance are zero return error +if(prior_var <= 0 && obs_error_var <= 0) + err = 1; + return; +end + +% Compute the posterior mean and variance +% If prior variance is 0, posterior mean is prior_mean and variance is 0 +if(prior_var == 0) + post_mean = prior_mean; + post_var = 0; +elseif(obs_error_var == 0) +% If obs_error_var is 0, posterior mean is observation and variance is 0 + post_mean = observation; + post_var = 0; +else +% Use product of gaussians + % Compute the posterior variance + post_var = 1 / (1 / prior_var + 1 / obs_error_var); + + % Compute posterior mean + post_mean = post_var * (prior_mean / prior_var + observation / obs_error_var); +end + +% Generate the perturbed observations by adding +% draw from Normal(0, obs_error_sd) +temp_obs = observation + sqrt(obs_error_var) * randn(size(ensemble)); + +% Adjust so that perturbed observations have mean = to observation +% This is technically an enhancement of earliest EnKFs +temp_obs = temp_obs - mean(temp_obs) + observation; + +% Compute new ensemble members by taking product of prior ensemble +% members and perturbed obs pairs +updated_ens = post_var * (ensemble / prior_var + temp_obs / obs_error_var); + +% Increments are difference between updated and original ensemble +obs_increments = updated_ens - ensemble; + +% Following are enhancements that change characteristics of EnKF +% Coding is not finalized so do NOT just uncomment +% Could also adjust the mean and variance of the final sample; +% This can greatly improve and change the behavior +% Shift the prior ensemble to have the posterior mean +%%%updated_ensemble = ensemble - prior_mean + post_mean; + +% Contract the ensemble to have the posterior_variance +%%%var_ratio = post_var / prior_var; +%%%updated_ensemble = sqrt(var_ratio) * (updated_ensemble - post_mean) + post_mean; + +% Compute the increments +%%%obs_increments = updated_ensemble - ensemble; + Property changes on: DART/trunk/DART_LAB/matlab/obs_increment_enkf.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/obs_increment_rhf.m =================================================================== --- DART/trunk/DART_LAB/matlab/obs_increment_rhf.m (rev 0) +++ DART/trunk/DART_LAB/matlab/obs_increment_rhf.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,177 @@ +function [obs_increments, err] = obs_increment_eakf(ensemble, observation, obs_error_var) +% Computes increments for a rank histogram filter +% Need to discuss the available options eventually +% For now this implements the default options + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Set error return to default successful +err = 0; + +% Get the ensemble size +ens_size = size(ensemble, 2); +prior_sd = std(ensemble); +prior_var = prior_sd^2; + +% Sort the ensemble members and keep the indices +[x, e_ind] = sort(ensemble); + +% Compute the likelihood of each member given the observation +like = exp(-1 * (x - observation).^2 / (2 * obs_error_var)); + +% Compute the mean likelihood density in each interior bin +for i = 2:ens_size + like_dense(i) = (like(i - 1) + like(i)) / 2; +end + +% For unit normal, find distance from mean to where cdf is 1/(n+1) +dist_for_unit_sd = -1 * weighted_norm_inv(1, 0, 1, 1/(ens_size + 1)); + +% Variance of tails is just sample prior variance +% Mean is adjusted so that 1/(ens_size + 1) is outside +left_mean = x(1) + dist_for_unit_sd * prior_sd; +left_var = prior_var; +left_sd = prior_sd; + +% Same for the right tail +right_mean = x(ens_size) - dist_for_unit_sd * prior_sd; +right_var = prior_var; +right_sd = prior_sd; + +% Eventually want to support options, for now +gaussian_likelihood_tails = false; + +if(gaussian_likelihood_tails) + % Need to fill this in +else + % Block to do flat tails for likelihood follows + % This removes assumptions about likelihood and cuts cost + new_var_left = left_var; + new_sd_left = left_sd; + new_mean_left = left_mean; + prod_weight_left = like(1); + mass(1) = like(1) / (ens_size + 1); + + % Same for right tail + new_var_right = right_var; + new_sd_right = right_sd; + new_mean_right = right_mean; + prod_weight_right = like(ens_size); + mass(ens_size + 1) = like(ens_size) / (ens_size + 1); + % End block for flat tail likelihood +end + +% The mass in each interior box is the height times the width +% The height of the likelihood is like_dense +% For the prior, mass is 1 / ((n+1) width), and mass = height x widt so +% The height of the prior is 1 / ((n+1) width); Multiplying by width leaves 1/(n+1) + +% In prior, have 1/(n+1) mass in each bin, multiply by mean likelihood +% density to get approximate mass in updated bin +for i = 2:ens_size + mass(i) = like_dense(i) / (ens_size + 1); + % Height of prior in this bin is mass/width; Only needed for trapezoidal + % If two ensemble members are the same, set height to -1 as flag + if(x(i) == x(i-1)) + height(i) = -1; + else + height(i) = 1 / ((ens_size + 1) * (x(i) - x(i-1))); + end +end + +% Now normalize the mass in the different bins to get a pdf +mass_sum = sum(mass); +nmass = mass / mass_sum; + +% Get the weight for the final normalized tail gaussians +% This is the same as left_amp=(ens_size + 1)*nmass(1) +left_amp = prod_weight_left / mass_sum; +% This is the same as right_amp=(ens_size + 1)*nmass(ens_size+1) +right_amp = prod_weight_right / mass_sum; + +% Find cumulative mass at each box boundary and middle boundary +cumul_mass(1) = 0; +for i = 1:ens_size + 1 + cumul_mass(i+1) = cumul_mass(i) + nmass(i); +end + +% Begin internal box search at bottom of lowest box +lowest_box = 1; + +% Find each new ensemble member's location +for i = 1:ens_size + % Each update ensemble member has 1/(n+1) mass before it + umass = i / (ens_size + 1); + + % If it is in the inner or outer range have to use normal + if(umass < cumul_mass(2)) + % It is in the left tail + % Get position of x in weighted gaussian where the cdf has value umass + new_ens(i) = weighted_norm_inv(left_amp, new_mean_left, ... + new_sd_left, umass); + elseif (umass > cumul_mass(ens_size + 1)) + % It's in the right tail + % Get the position of x in weighted gaussian where the cdf has value umass + new_ens(i) = weighted_norm_inv(right_amp, new_mean_right, ... + new_sd_right, 1 - umass); + % Coming in from the right, use symmetry after pretending it's on left + new_ens(i) = new_mean_right + (new_mean_right - new_ens(i)); + else + % In one of the inner boxes + for j = lowest_box:ens_size - 1 + % Find the box that this mass is in + if(umass >= cumul_mass(j+1) && umass <= cumul_mass(j+2)) + + % Only rectangular is implemented for now + rectangular_quadrature = true; + + if(rectangular_quadrature) + % Rectangular quadrature block first + % Linearly interpolate in mass + new_ens(i) = x(j) + ((umass - cumul_mass(j+1)) / ... + (cumul_mass(j+2) - cumul_mass(j+1))) * (x(j+1) - x(j)); + else + % Trapezoidal interpolation block goes here + end + + % Don't need to search lower boxes again + lowest_box = j; + break + end + end + end +end + +% Convert to increments for unsorted +for i = 1:ens_size + obs_increments(e_ind(i)) = new_ens(i) - x(i); +end + + +%----------------------------------------------- + + +function [x] = weighted_norm_inv(alpha, mean, sd, p) + +% Find the value of x for which the cdf of a N(mean, sd) +% multiplied times alpha has value p. + +% Can search in a standard normal, then multiply by sd at end and add mean +% Divide p by alpha to get the right place for weighted normal +np = p / alpha; + +% Find spot in standard normal +x = norminv(np, 0, 1); + +% Add in the mean and normalize by sd +x = mean + x * sd; + Property changes on: DART/trunk/DART_LAB/matlab/obs_increment_rhf.m ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/x-matlab Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native Added: DART/trunk/DART_LAB/matlab/oned_ensemble.fig =================================================================== (Binary files differ) Property changes on: DART/trunk/DART_LAB/matlab/oned_ensemble.fig ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + application/octet-stream Added: DART/trunk/DART_LAB/matlab/oned_ensemble.m =================================================================== --- DART/trunk/DART_LAB/matlab/oned_ensemble.m (rev 0) +++ DART/trunk/DART_LAB/matlab/oned_ensemble.m 2009-08-25 23:04:35 UTC (rev 4011) @@ -0,0 +1,473 @@ +function varargout = oned_ensemble(varargin) +% ONED_ENSEMBLE explore the details of ensemble data assimilation for a scalar. +% +% Click on the 'Create New Ensemble' button to activate the interactive +% observation generation mechanism and lay down a set of 'observations' +% representative of your ensemble. (Think: Some H() operator has +% converted the model state to an expected observation.) +% +% After you have an ensemble and an observation, choose an assimilation +% algorithm and click 'Update Ensemble'. The algorithm is applied and the +% Posterior (blue) is plotted below the Prior (green). Choose 'EAKF' +% and click 'Update' ... multiple times. Do the same for 'EnKF' and +% 'RHF'. Hmnnnn .... +% +% change the Observation Error SD, lay down an ensemble pretty far away +% from the observation - have fun with it. +% +% See also: gaussian_product, oned_model, twod_ensemble, run_lorenz_63, +% run_lorenz_96 + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2009, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ + +% Last Modified by GUIDE v2.5 25-Mar-2009 14:34:04 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @oned_ensemble_OpeningFcn, ... + 'gui_OutputFcn', @oned_ensemble_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before oned_ensemble is made visible. +function oned_ensemble_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to oned_ensemble (see VARARGIN) + +help oned_ensemble + +% Choose default command line output for oned_ensemble +handles.output = hObject; + +% Insert the ensemble structure into this +handles.ens_size = 0; +handles.ens_members = 0; +handles.h_obs_plot = 0; +handles.h_update_ens = 0; +handles.h_ens_member = 0; +handles.h_obs_ast = 0; + +% Update handles structure +guidata(hObject, handles); + +% Go ahead and plot the initial observational error distribution +h_observation = get(handles.edit1); +h_obs_error_sd = get(handles.edit2); +observation = str2double(h_observation.String); +obs_error_sd = str2double(h_obs_error_sd.String); +handles.h_obs_plot = plot_gaussian(observation, obs_error_sd, 1); +set(handles.h_obs_plot, 'Color', 'r', 'Linestyle', '--', 'Linewidth', 2); +hold on + +% Plot an asterisk +handles.h_obs_ast = plot(observation, 0, 'r*', 'MarkerSize', 16); + +% Set a basic plotting domain range that includes mean +/- 3 obs SDs +lower = observation - 3*obs_error_sd; +upper = observation + 3*obs_error_sd; +axis([lower upper -0.2 1]); + + +set(gca, 'YTick', [0 0.2 0.4 0.6 0.8]); +set(gca, 'YTickLabel', [0 0.2 0.4 0.6 0.8]); + +hold on +plot([lower upper], [0 0], 'k', 'Linewidth', 2); + +% Update handles structure +guidata(hObject, handles); + + +% UIWAIT makes oned_ensemble wait for user response (see UIRESUME) +% uiwait(handles.figure1); + + +%---------------------------------------------------------------------- + + +% --- Outputs from this function are returned to the command line. +function varargout = oned_ensemble_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure +varargout{1} = handles.output; + + +%---------------------------------------------------------------------- + + +% --- Executes on button press in pushbutton1. @@ Diff output truncated at 40000 characters. @@ From nancy at ucar.edu Tue Aug 25 17:22:31 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Tue, 25 Aug 2009 17:22:31 -0600 (MDT) Subject: [Dart-dev] [4012] DART/trunk/models/POP/matlab/Check_ud.m: Better output format for reporting differences. Message-ID: <200908252322.n7PNMVna015519@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090825/a2e73222/attachment.html -------------- next part -------------- Modified: DART/trunk/models/POP/matlab/Check_ud.m =================================================================== --- DART/trunk/models/POP/matlab/Check_ud.m 2009-08-25 23:04:35 UTC (rev 4011) +++ DART/trunk/models/POP/matlab/Check_ud.m 2009-08-25 23:22:31 UTC (rev 4012) @@ -1,14 +1,24 @@ -function [dart pop] = Check_ud(dartfile,popfile) -% Check_ud : check the conversion of a POP restart to a DART state vector. +function [dart pop] = Check_ud(popfile,dartfile) +% Check_ud : check pop_to_dart.f90 ... the conversion of a POP restart to a DART state vector file. +% +% popfile = 'pop.r.nc' % dartfile = 'assim_model_state_ud'; -% popfile = 'pop.r.nc' -% x = Check_ud(dartfile,popfile); +% x = Check_ud(popfile, dartfile); % -% -% dartfile = '/fs/image/home/thoar/SVN/DART/models/POP/work/assim_model_state_ud'; % popfile = '/fs/image/home/thoar/SVN/DART/models/POP/work/cx3.dart.001.pop.r.0002-01-01-00000.nc'; -% [dart pop] = Check_ud(dartfile,popfile); +% dartfile = '/fs/image/home/thoar/SVN/DART/models/POP/work/perfect_ics'; +% [dart pop] = Check_ud(popfile, dartfile); + +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2007, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html % +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ % Read the original POP file values. % The nc_varget() function returns the variables with the fastest @@ -80,13 +90,47 @@ % Find the range of the mismatch -Sdiff = pop.S - dart.S; [min( Sdiff(:)) max( Sdiff(:))] -Tdiff = pop.T - dart.T; [min( Tdiff(:)) max( Tdiff(:))] -Udiff = pop.U - dart.U; [min( Udiff(:)) max( Udiff(:))] -Vdiff = pop.V - dart.V; [min( Vdiff(:)) max( Vdiff(:))] -PSURFdiff = pop.PSURF - dart.PSURF; [min(PSURFdiff(:)) max(PSURFdiff(:))] +d = pop.S - dart.S; disp(sprintf('S diffs are %0.8g %0.8g',min(d(:)),max(d(:)))) +d = pop.T - dart.T; disp(sprintf('T diffs are %0.8g %0.8g',min(d(:)),max(d(:)))) +d = pop.U - dart.U; disp(sprintf('U diffs are %0.8g %0.8g',min(d(:)),max(d(:)))) +d = pop.V - dart.V; disp(sprintf('V diffs are %0.8g %0.8g',min(d(:)),max(d(:)))) +d = pop.PSURF - dart.PSURF; disp(sprintf('PSURF diffs are %0.8g %0.8g',min(d(:)),max(d(:)))) +% As an added bonus, we create an 'assim_model_state_ic' file with an +% advance-to-time one day in the future. +% Open and read timetag for state +fid = fopen(dartfile,'rb','ieee-le'); +trec1 = fread(fid,1,'int32'); +seconds = fread(fid,1,'int32'); +days = fread(fid,1,'int32'); +trecN = fread(fid,1,'int32'); + +% read state vector variables. +rec1 = fread(fid, 1, 'int32'); +datvec = fread(fid, n3ditems+n2ditems, 'float64'); +recN = fread(fid, 1, 'int32'); +fclose(fid); + +% Open and write advance_to_time +fid = fopen('test.ic','wb','ieee-le'); +fwrite(fid, trec1,'int32'); +fwrite(fid,seconds,'int32'); +fwrite(fid, days,'int32'); +fwrite(fid, trecN,'int32'); + +fwrite(fid, trec1,'int32'); +fwrite(fid,seconds,'int32'); +fwrite(fid, days+1,'int32'); +fwrite(fid, trecN,'int32'); + +% read state vector variables. +fwrite(fid, rec1, 'int32'); +fwrite(fid, datvec, 'float64'); +fwrite(fid, recN, 'int32'); +fclose(fid); + + function C = get_3D_permuted(fid, shape, typestr) datasize = prod(shape); A = fread(fid, prod(shape), typestr); From nancy at ucar.edu Thu Aug 27 14:08:07 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Thu, 27 Aug 2009 14:08:07 -0600 (MDT) Subject: [Dart-dev] [4013] DART/trunk/shell_scripts: Template files which have the right syntax for various shells. Message-ID: <200908272008.n7RK87A8011275@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090827/c8f29612/attachment.html -------------- next part -------------- Added: DART/trunk/shell_scripts/day_template.bash =================================================================== --- DART/trunk/shell_scripts/day_template.bash (rev 0) +++ DART/trunk/shell_scripts/day_template.bash 2009-08-27 20:08:07 UTC (rev 4013) @@ -0,0 +1,85 @@ +#!/bin/bash + +# this is a template for a shell script that can loop +# over multiple days and roll over month boundaries +# or even year boundaries. see the section inside the loop +# for the 'your code goes here' part. look for the string ADDME. +# this script requires the executable 'advance_time' to be +# built and exist in the current directory, and advance_time +# requires an input.nml namelist file. + +# it computes the gregorian day if useful, and makes sure +# the days and months are always 2 digits long. + +# set the first and last days. can roll over month and year boundaries. +let start_year=2006 +let start_month=1 +let start_day=31 + +let end_year=2006 +let end_month=2 +let end_day=3 + +# put more stuff here if you have user settable options + +# end of things you should have to set in this script + +# convert the start and stop times to gregorian days, so we can +# compute total number of days including rolling over month and +# year boundaries. make sure all values have leading 0s if they +# are < 10. do the end time first so we can use the same values +# to set the initial day while we are doing the total day calc. + +# the output of advance time with the -g input is: +# gregorian_day_number seconds +# use ${var[0]} to return just the day number + +mon2=`printf %02d $end_month` +day2=`printf %02d $end_day` +end_d=(`echo ${end_year}${mon2}${day2}00 0 -g | ./advance_time`) + +mon2=`printf %02d $start_month` +day2=`printf %02d $start_day` +start_d=(`echo ${start_year}${mon2}${day2}00 0 -g | ./advance_time`) + +# the output of this call is a string YYYYMMDDHH +# see below for help in how to easily parse this up into words +curday=`echo ${start_year}${mon2}${day2}00 0 | ./advance_time` + +# how many total days are going to be processed (for the loop counter) +let totaldays=${end_d[0]}-${start_d[0]} +let totaldays=$totaldays+1 + +# loop over each day +let d=1 +while (( d <= totaldays)) ; do + + # parse out the parts from a string which is YYYYMMDDHH + # use cut with the byte option to pull out columns 1-4, 5-6, and 7-8 + year=`echo $curday | cut -b1-4` + month=`echo $curday | cut -b5-6` + day=`echo $curday | cut -b7-8` + + # compute the equivalent gregorian day here. + g=(`echo ${year}${month}${day}00 0 -g | ./advance_time`) + greg=${g[0]} + + # status/debug - comment in or out as desired. + echo starting processing for ${year} ${month} ${day} + echo which is gregorian day: $greg + + + # your code goes here. + # use $year, $month, $day, and $greg as needed + + + # advance the day; the output is YYYYMMDD00 + curday=`echo ${year}${month}${day}00 +1d | ./advance_time` + + # advance the loop counter + let d=d+1 + +done + +exit 0 + Property changes on: DART/trunk/shell_scripts/day_template.bash ___________________________________________________________________ Name: svn:executable + * Added: DART/trunk/shell_scripts/day_template.csh =================================================================== --- DART/trunk/shell_scripts/day_template.csh (rev 0) +++ DART/trunk/shell_scripts/day_template.csh 2009-08-27 20:08:07 UTC (rev 4013) @@ -0,0 +1,87 @@ +#!/bin/csh + +# this is a template for a shell script that can loop +# over multiple days and roll over month boundaries +# or even year boundaries. see the section inside the loop +# for the 'your code goes here' part. look for the string ADDME. +# this script requires the executable 'advance_time' to be +# built and exist in the current directory, and advance_time +# requires an input.nml namelist file. + +# it computes the gregorian day if useful, and makes sure +# the days and months are always 2 digits long. + +# set the first and last days. can roll over month and year boundaries. +set start_year=2006 +set start_month=10 +set start_day=31 + +set end_year=2006 +set end_month=11 +set end_day=3 + +# put more stuff here if you have user settable options + +# end of things you should have to set in this script + +# convert the start and stop times to gregorian days, so we can +# compute total number of days including rolling over month and +# year boundaries. make sure all values have leading 0s if they +# are < 10. do the end time first so we can use the same values +# to set the initial day while we are doing the total day calc. + +# the output of advance time with the -g input is: +# gregorian_day_number seconds +# use $var[1] to return just the day number + +set mon2=`printf %02d $end_month` +set day2=`printf %02d $end_day` +set end_d=(`echo ${end_year}${mon2}${day2}00 0 -g | ./advance_time`) + +set mon2=`printf %02d $start_month` +set day2=`printf %02d $start_day` +set start_d=(`echo ${start_year}${mon2}${day2}00 0 -g | ./advance_time`) + +# the output of this call is a string YYYYMMDDHH +# see below for help in how to easily parse this up into words +set curday=`echo ${start_year}${mon2}${day2}00 0 | ./advance_time` + +# how many total days are going to be processed (for the loop counter) +# note that the parens below are necessary; otherwise the computation +# does total = end - (start+1), or total = end - start - 1, which is +# not how elementary math is supposed to work. +@ totaldays = ( $end_d[1] - $start_d[1] ) + 1 + +# loop over each day +set d=1 +while ( $d <= $totaldays ) + + # parse out the parts from a string which is YYYYMMDDHH + # use cut with the byte option to pull out columns 1-4, 5-6, and 7-8 + set year=`echo $curday | cut -b1-4` + set month=`echo $curday | cut -b5-6` + set day=`echo $curday | cut -b7-8` + + # compute the equivalent gregorian day here. + set g=(`echo ${year}${month}${day}00 0 -g | ./advance_time`) + set greg=$g[1] + + # status/debug - comment in or out as desired. + echo starting processing for ${year} ${month} ${day} + echo which is gregorian day: $greg + + + # your code goes here. + # use $year, $month, $day, and $greg as needed. + + + # advance the day; the output is YYYYMMDD00 + set curday=`echo ${year}${month}${day}00 +1d | ./advance_time` + + # advance the loop counter + @ d += 1 + +end + +exit 0 + Property changes on: DART/trunk/shell_scripts/day_template.csh ___________________________________________________________________ Name: svn:executable + * Name: svn:keywords + Date Revision Author HeadURL Id Added: DART/trunk/shell_scripts/day_template.ksh =================================================================== --- DART/trunk/shell_scripts/day_template.ksh (rev 0) +++ DART/trunk/shell_scripts/day_template.ksh 2009-08-27 20:08:07 UTC (rev 4013) @@ -0,0 +1,84 @@ +#!/bin/ksh + +# this is a template for a shell script that can loop +# over multiple days and roll over month boundaries +# or even year boundaries. see the section inside the loop +# for the 'your code goes here' part. look for the string ADDME. +# this script requires the executable 'advance_time' to be +# built and exist in the current directory, and advance_time +# requires an input.nml namelist file. + +# it computes the gregorian day if useful, and makes sure +# the days and months are always 2 digits long. + +# set the first and last days. can roll over month and year boundaries. +let start_year=2006 +let start_month=1 +let start_day=31 + +let end_year=2006 +let end_month=2 +let end_day=3 + +# put more stuff here if you have user settable options + +# end of things you should have to set in this script + +# convert the start and stop times to gregorian days, so we can +# compute total number of days including rolling over month and +# year boundaries. make sure all values have leading 0s if they +# are < 10. do the end time first so we can use the same values +# to set the initial day while we are doing the total day calc. + +# the output of advance time with the -g input is: +# gregorian_day_number seconds +# use ${var[0]} to return just the day number + +mon2=`printf %02d $end_month` +day2=`printf %02d $end_day` +set -A end_d `echo ${end_year}${mon2}${day2}00 0 -g | ./advance_time` + +mon2=`printf %02d $start_month` +day2=`printf %02d $start_day` +set -A start_d `echo ${start_year}${mon2}${day2}00 0 -g | ./advance_time` + +# the output of this call is a string YYYYMMDDHH +# see below for help in how to easily parse this up into words +curday=`echo ${start_year}${mon2}${day2}00 0 | ./advance_time` + +# how many total days are going to be processed (for the loop counter) +let totaldays=${end_d[0]}-${start_d[0]}+1 + +# loop over each day +let d=1 +while (( d <= totaldays)) ; do + + # parse out the parts from a string which is YYYYMMDDHH + # use cut with the byte option to pull out columns 1-4, 5-6, and 7-8 + year=`echo $curday | cut -b1-4` + month=`echo $curday | cut -b5-6` + day=`echo $curday | cut -b7-8` + + # compute the equivalent gregorian day here. + set -A g `echo ${year}${month}${day}00 0 -g | ./advance_time` + greg=${g[0]} + + # status/debug - comment in or out as desired. + echo starting processing for ${year} ${month} ${day} + echo which is gregorian day: $greg + + + # your code goes here. + # use $year, $month, $day, and $greg as needed + + + # advance the day; the output is YYYYMMDD00 + curday=`echo ${year}${month}${day}00 +1d | ./advance_time` + + # advance the loop counter + let d=d+1 + +done + +exit 0 + Property changes on: DART/trunk/shell_scripts/day_template.ksh ___________________________________________________________________ Name: svn:executable + * Added: DART/trunk/shell_scripts/day_template.zsh =================================================================== --- DART/trunk/shell_scripts/day_template.zsh (rev 0) +++ DART/trunk/shell_scripts/day_template.zsh 2009-08-27 20:08:07 UTC (rev 4013) @@ -0,0 +1,84 @@ +#!/bin/zsh + +# this is a template for a shell script that can loop +# over multiple days and roll over month boundaries +# or even year boundaries. see the section inside the loop +# for the 'your code goes here' part. look for the string ADDME. +# this script requires the executable 'advance_time' to be +# built and exist in the current directory, and advance_time +# requires an input.nml namelist file. + +# it computes the gregorian day if useful, and makes sure +# the days and months are always 2 digits long. + +# set the first and last days. can roll over month and year boundaries. +let start_year=2006 +let start_month=1 +let start_day=31 + +let end_year=2006 +let end_month=2 +let end_day=3 + +# put more stuff here if you have user settable options + +# end of things you should have to set in this script + +# convert the start and stop times to gregorian days, so we can +# compute total number of days including rolling over month and +# year boundaries. make sure all values have leading 0s if they +# are < 10. do the end time first so we can use the same values +# to set the initial day while we are doing the total day calc. + +# the output of advance time with the -g input is: +# gregorian_day_number seconds +# use ${var[0]} to return just the day number + +mon2=`printf %02d $end_month` +day2=`printf %02d $end_day` +set -A end_d `echo ${end_year}${mon2}${day2}00 0 -g | ./advance_time` + +mon2=`printf %02d $start_month` +day2=`printf %02d $start_day` +set -A start_d `echo ${start_year}${mon2}${day2}00 0 -g | ./advance_time` + +# the output of this call is a string YYYYMMDDHH +# see below for help in how to easily parse this up into words +curday=`echo ${start_year}${mon2}${day2}00 0 | ./advance_time` + +# how many total days are going to be processed (for the loop counter) +let totaldays=${end_d[0]}-${start_d[0]}+1 + +# loop over each day +let d=1 +while (( d <= totaldays)) ; do + + # parse out the parts from a string which is YYYYMMDDHH + # use cut with the byte option to pull out columns 1-4, 5-6, and 7-8 + year=`echo $curday | cut -b1-4` + month=`echo $curday | cut -b5-6` + day=`echo $curday | cut -b7-8` + + # compute the equivalent gregorian day here. + set -A g `echo ${year}${month}${day}00 0 -g | ./advance_time` + greg=${g[0]} + + # status/debug - comment in or out as desired. + echo starting processing for ${year} ${month} ${day} + echo which is gregorian day: $greg + + + # your code goes here. + # use $year, $month, $day, and $greg as needed + + + # advance the day; the output is YYYYMMDD00 + curday=`echo ${year}${month}${day}00 +1d | ./advance_time` + + # advance the loop counter + let d=d+1 + +done + +exit 0 + Property changes on: DART/trunk/shell_scripts/day_template.zsh ___________________________________________________________________ Name: svn:executable + * From nancy at ucar.edu Thu Aug 27 14:08:40 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Thu, 27 Aug 2009 14:08:40 -0600 (MDT) Subject: [Dart-dev] [4014] DART/trunk/observations/gps/work/path_names_advance_time: Fix the name of the utilities_mod file. Message-ID: <200908272008.n7RK8e0U011871@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090827/19958cb3/attachment.html -------------- next part -------------- Modified: DART/trunk/observations/gps/work/path_names_advance_time =================================================================== --- DART/trunk/observations/gps/work/path_names_advance_time 2009-08-27 20:08:07 UTC (rev 4013) +++ DART/trunk/observations/gps/work/path_names_advance_time 2009-08-27 20:08:40 UTC (rev 4014) @@ -1,6 +1,6 @@ time_manager/advance_time.f90 time_manager/time_manager_mod.f90 common/types_mod.f90 -utilities/utilities_lite_mod.f90 +utilities/utilities_mod.f90 utilities/parse_args_mod.f90 mpi_utilities/null_mpi_utilities_mod.f90 From nancy at ucar.edu Thu Aug 27 14:13:52 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Thu, 27 Aug 2009 14:13:52 -0600 (MDT) Subject: [Dart-dev] [4015] DART/trunk/models/wrf/work: Add mkmf and path_names files for the time utility which uses the DART Message-ID: <200908272013.n7RKDqMb016947@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090827/b121a68f/attachment.html -------------- next part -------------- Added: DART/trunk/models/wrf/work/mkmf_advance_time =================================================================== --- DART/trunk/models/wrf/work/mkmf_advance_time (rev 0) +++ DART/trunk/models/wrf/work/mkmf_advance_time 2009-08-27 20:13:51 UTC (rev 4015) @@ -0,0 +1,15 @@ +#!/bin/csh +# +# Data Assimilation Research Testbed -- DART +# Copyright 2004-2007, Data Assimilation Research Section +# University Corporation for Atmospheric Research +# Licensed under the GPL -- www.gpl.org/licenses/gpl.html +# +# +# $URL: http://subversion.ucar.edu/DAReS/DART/trunk/models/bgrid_solo/work/mkmf_merge_obs_seq $ +# $Id: mkmf_merge_obs_seq 2691 2007-03-11 18:18:09Z thoar $ +# $Revision: 2691 $ +# $Date: 2007-03-11 12:18:09 -0600 (Sun, 11 Mar 2007) $ +# +../../../mkmf/mkmf -p advance_time -t ../../../mkmf/mkmf.template -c"-Duse_netCDF" \ + -a "../../.." path_names_advance_time Property changes on: DART/trunk/models/wrf/work/mkmf_advance_time ___________________________________________________________________ Name: svn:executable + * Added: DART/trunk/models/wrf/work/path_names_advance_time =================================================================== --- DART/trunk/models/wrf/work/path_names_advance_time (rev 0) +++ DART/trunk/models/wrf/work/path_names_advance_time 2009-08-27 20:13:51 UTC (rev 4015) @@ -0,0 +1,6 @@ +time_manager/advance_time.f90 +time_manager/time_manager_mod.f90 +common/types_mod.f90 +utilities/utilities_mod.f90 +utilities/parse_args_mod.f90 +mpi_utilities/null_mpi_utilities_mod.f90 From nancy at ucar.edu Thu Aug 27 14:15:42 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Thu, 27 Aug 2009 14:15:42 -0600 (MDT) Subject: [Dart-dev] [4016] DART/trunk/observations/AIRS/airs_obs_mod.f90: Use the parameter defined in a standard module to set the length of the Message-ID: <200908272015.n7RKFgkx018893@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090827/43aaeae2/attachment-0001.html -------------- next part -------------- Modified: DART/trunk/observations/AIRS/airs_obs_mod.f90 =================================================================== --- DART/trunk/observations/AIRS/airs_obs_mod.f90 2009-08-27 20:13:51 UTC (rev 4015) +++ DART/trunk/observations/AIRS/airs_obs_mod.f90 2009-08-27 20:15:42 UTC (rev 4016) @@ -11,7 +11,7 @@ ! $Revision: 3809 $ ! $Date: 2009-04-13 10:21:33 -0600 (Mon, 13 Apr 2009) $ -use types_mod, only : r4, r8, digits12, deg2rad, rad2deg +use types_mod, only : r4, r8, digits12, deg2rad, rad2deg, metadatalength use obs_def_mod, only : obs_def_type, get_obs_def_time, read_obs_def, & write_obs_def, destroy_obs_def, & @@ -61,7 +61,7 @@ logical :: DEBUG = .false. -real(r8), parameter :: mb_to_hPa = 100.0 ! millibars to hectopascals +real(r8), parameter :: mb_to_Pa = 100.0 ! millibars to pascals ! the sizes of the Temperature arrays are: ! (AIRS_RET_STDPRESSURELAY, AIRS_RET_GEOXTRACK, AIRS_RET_GEOTRACK) @@ -126,7 +126,7 @@ type(time_type) :: obs_time, base_time, pre_time, time -character(len = 129) :: meta_data +character(len = metadatalength) :: meta_data if ( .not. module_initialized ) call initialize_module @@ -260,7 +260,7 @@ obs_var = granule%TAirStdErr(ivert, icol, irow) * & granule%TAirStdErr(ivert, icol, irow) - vloc = granule%pressStd(ivert) * mb_to_hPa + vloc = granule%pressStd(ivert) * mb_to_Pa call real_obs(num_copies, num_qc, obs, olon, olat, vloc, obs_value, & obs_var, tqc, AIRS_TEMPERATURE, which_vert, seconds, days) @@ -299,7 +299,7 @@ obs_value = Q(ivert, icol, irow) obs_var = Q_err(ivert, icol, irow) * Q_err(ivert, icol, irow) - vloc = granule%pressH2O(ivert) * mb_to_hPa + vloc = granule%pressH2O(ivert) * mb_to_Pa call real_obs(num_copies, num_qc, obs, olon, olat, vloc, obs_value, & obs_var, qqc, AIRS_SPECIFIC_HUMIDITY, which_vert, seconds, days) From nancy at ucar.edu Thu Aug 27 14:17:01 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Thu, 27 Aug 2009 14:17:01 -0600 (MDT) Subject: [Dart-dev] [4017] DART/trunk/observations/AIRS/work: Add mkmf and path_names files to build the obs_seq tool in Message-ID: <200908272017.n7RKH1nD020140@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090827/ad69b411/attachment.html -------------- next part -------------- Added: DART/trunk/observations/AIRS/work/mkmf_obs_sequence_tool =================================================================== --- DART/trunk/observations/AIRS/work/mkmf_obs_sequence_tool (rev 0) +++ DART/trunk/observations/AIRS/work/mkmf_obs_sequence_tool 2009-08-27 20:17:01 UTC (rev 4017) @@ -0,0 +1,15 @@ +#!/bin/csh +# +# Data Assimilation Research Testbed -- DART +# Copyright 2004-2007, Data Assimilation Research Section +# University Corporation for Atmospheric Research +# Licensed under the GPL -- www.gpl.org/licenses/gpl.html +# +# +# $URL: https://subversion.ucar.edu/DAReS/DART/trunk/observations/utilities/threed_sphere/mkmf_obs_sequence_tool $ +# $Id: mkmf_obs_sequence_tool 3836 2009-05-01 00:25:15Z thoar $ +# $Revision: 3836 $ +# $Date: 2009-04-30 18:25:15 -0600 (Thu, 30 Apr 2009) $ +# +../../../mkmf/mkmf -p obs_sequence_tool -t ../../../mkmf/mkmf.template -c"-Duse_netCDF" \ + -a "../../.." path_names_obs_sequence_tool Property changes on: DART/trunk/observations/AIRS/work/mkmf_obs_sequence_tool ___________________________________________________________________ Name: svn:executable + * Added: DART/trunk/observations/AIRS/work/path_names_obs_sequence_tool =================================================================== --- DART/trunk/observations/AIRS/work/path_names_obs_sequence_tool (rev 0) +++ DART/trunk/observations/AIRS/work/path_names_obs_sequence_tool 2009-08-27 20:17:01 UTC (rev 4017) @@ -0,0 +1,13 @@ +assim_model/assim_model_mod.f90 +common/types_mod.f90 +location/threed_sphere/location_mod.f90 +models/template/model_mod.f90 +mpi_utilities/null_mpi_utilities_mod.f90 +obs_def/obs_def_mod.f90 +obs_kind/obs_kind_mod.f90 +obs_sequence/obs_sequence_mod.f90 +obs_sequence/obs_sequence_tool.f90 +random_nr/random_nr_mod.f90 +random_seq/random_seq_mod.f90 +time_manager/time_manager_mod.f90 +utilities/utilities_mod.f90 From nancy at ucar.edu Thu Aug 27 14:17:34 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Thu, 27 Aug 2009 14:17:34 -0600 (MDT) Subject: [Dart-dev] [4018] DART/trunk/observations/AIRS/work: mkmf and path_names files for the advance_time util, which is used Message-ID: <200908272017.n7RKHXqn020813@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090827/fd3e2cb2/attachment.html -------------- next part -------------- Added: DART/trunk/observations/AIRS/work/mkmf_advance_time =================================================================== --- DART/trunk/observations/AIRS/work/mkmf_advance_time (rev 0) +++ DART/trunk/observations/AIRS/work/mkmf_advance_time 2009-08-27 20:17:33 UTC (rev 4018) @@ -0,0 +1,15 @@ +#!/bin/csh +# +# Data Assimilation Research Testbed -- DART +# Copyright 2004-2007, Data Assimilation Research Section +# University Corporation for Atmospheric Research +# Licensed under the GPL -- www.gpl.org/licenses/gpl.html +# +# +# $URL: http://subversion.ucar.edu/DAReS/DART/trunk/models/bgrid_solo/work/mkmf_merge_obs_seq $ +# $Id: mkmf_merge_obs_seq 2691 2007-03-11 18:18:09Z thoar $ +# $Revision: 2691 $ +# $Date: 2007-03-11 12:18:09 -0600 (Sun, 11 Mar 2007) $ +# +../../../mkmf/mkmf -p advance_time -t ../../../mkmf/mkmf.template -c"-Duse_netCDF" \ + -a "../../.." path_names_advance_time Property changes on: DART/trunk/observations/AIRS/work/mkmf_advance_time ___________________________________________________________________ Name: svn:executable + * Added: DART/trunk/observations/AIRS/work/path_names_advance_time =================================================================== --- DART/trunk/observations/AIRS/work/path_names_advance_time (rev 0) +++ DART/trunk/observations/AIRS/work/path_names_advance_time 2009-08-27 20:17:33 UTC (rev 4018) @@ -0,0 +1,6 @@ +time_manager/advance_time.f90 +time_manager/time_manager_mod.f90 +common/types_mod.f90 +utilities/utilities_lite_mod.f90 +utilities/parse_args_mod.f90 +mpi_utilities/null_mpi_utilities_mod.f90 From nancy at ucar.edu Thu Aug 27 14:19:52 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Thu, 27 Aug 2009 14:19:52 -0600 (MDT) Subject: [Dart-dev] [4019] DART/trunk/observations/AIRS: The scripts used to generate multiple days of AIRS data files, with Message-ID: <200908272019.n7RKJqkT023277@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090827/4098b79d/attachment.html -------------- next part -------------- Added: DART/trunk/observations/AIRS/shell_scripts/README =================================================================== --- DART/trunk/observations/AIRS/shell_scripts/README (rev 0) +++ DART/trunk/observations/AIRS/shell_scripts/README 2009-08-27 20:19:52 UTC (rev 4019) @@ -0,0 +1,7 @@ + +These scripts are intended to help download the original AIRS hdf +data files, convert them in bulk, and merge the resulting obs_seq files. + +In most cases, they're intended to be copied over to the ../work directory +and then customized for the particular time period and local directory names. + Added: DART/trunk/observations/AIRS/shell_scripts/download.sh =================================================================== --- DART/trunk/observations/AIRS/shell_scripts/download.sh (rev 0) +++ DART/trunk/observations/AIRS/shell_scripts/download.sh 2009-08-27 20:19:52 UTC (rev 4019) @@ -0,0 +1,58 @@ +#!/bin/bash + +# download the requested tar files from the NCAR mass store. + +# set the first and last days. can roll over +# month and year boundaries now! +let start_year=2006 +let start_month=10 +let start_day=1 + +let end_year=2007 +let end_month=1 +let end_day=31 + +# end of things you should have to set in this script + +# convert the start and stop times to gregorian days, so we can +# compute total number of days including rolling over month and +# year boundaries. make sure all values have leading 0s if they +# are < 10. do the end time first so we can use the same values +# to set the initial day while we are doing the total day calc. +mon2=`printf %02d $end_month` +day2=`printf %02d $end_day` +end_d=(`echo ${end_year}${mon2}${day2}00 0 -g | ./advance_time`) + +mon2=`printf %02d $start_month` +day2=`printf %02d $start_day` +start_d=(`echo ${start_year}${mon2}${day2}00 0 -g | ./advance_time`) + +curday=(`echo ${start_year}${mon2}${day2}00 0 | ./advance_time`) + +# how many total days are going to be converted (for the loop counter) +let totaldays=${end_d[0]}-${start_d[0]}+1 + +# loop over each day +let d=1 +while (( d <= totaldays)) ; do + + # parse out the parts from a string which is YYYYMMDDHH + year=${curday:0:4} + month=${curday:4:2} + day=${curday:6:2} + + + echo getting ${year}${month}${day}.tar from mass store + msrcp mss:/MIJEONG/AIRS/V5/L2/${year}${month}/${year}${month}${day}.tar . + + + # advance the day; the output is YYYYMMDD00 + curday=(`echo ${year}${month}${day}00 +1d | ./advance_time`) + + # advance the loop counter + let d=d+1 + +done + +exit 0 + Property changes on: DART/trunk/observations/AIRS/shell_scripts/download.sh ___________________________________________________________________ Name: svn:executable + * Added: DART/trunk/observations/AIRS/shell_scripts/mergeit.sh =================================================================== --- DART/trunk/observations/AIRS/shell_scripts/mergeit.sh (rev 0) +++ DART/trunk/observations/AIRS/shell_scripts/mergeit.sh 2009-08-27 20:19:52 UTC (rev 4019) @@ -0,0 +1,94 @@ +#!/bin/bash + +# merge the files into "daily" files which start at 03:01Z +# and end at 03:00Z the following day. (the name of the file +# is the first day.) + +# set the first and last days to be merged. can roll over +# month and year boundaries now! note that for the end day, +# you need at least the first 40ish files from the following day +# for the merge to have the right data (from 0Z to 3Z) available. + +let start_year=2006 +let start_month=10 +let start_day=1 + +let end_year=2007 +let end_month=1 +let end_day=31 + +# end of things you should have to set in this script + +# convert the start and stop times to gregorian days, so we can +# compute total number of days including rolling over month and +# year boundaries. make sure all values have leading 0s if they +# are < 10. do the end time first so we can use the same values +# to set the initial day while we are doing the total day calc. + +# these outputs from advance time (with the -g flag) are +# 2 integers: gregorian_day_number seconds +# and since we don't set hours, minutes, or seconds, the second +# number is always 0 and uninteresting for us. +mon2=`printf %02d $end_month` +day2=`printf %02d $end_day` +end_d=(`echo ${end_year}${mon2}${day2}00 0 -g | ./advance_time`) + +mon2=`printf %02d $start_month` +day2=`printf %02d $start_day` +start_d=(`echo ${start_year}${mon2}${day2}00 0 -g | ./advance_time`) + +# these are a string in the format YYYYMMDDHH +# do them here to prime the loop below which first takes them apart. +curday=(`echo ${start_year}${mon2}${day2}00 0 | ./advance_time`) +nextday=(`echo ${start_year}${mon2}${day2}00 +1d | ./advance_time`) + +# how many total days are going to be merged (for the loop counter) +# (pull out the first of the 2 numbers which are output from advance_time) +let totaldays=${end_d[0]}-${start_d[0]}+1 + +# loop over each day +let d=1 +while (( d <= totaldays)) ; do + + # parse out the parts from a string which is YYYYMMDDHH + # both for the current day and tomorrow + cyear=${curday:0:4} + cmonth=${curday:4:2} + cday=${curday:6:2} + nyear=${nextday:0:4} + nmonth=${nextday:4:2} + nday=${nextday:6:2} + + # compute the equivalent gregorian days here. + g=(`echo ${cyear}${cmonth}${cday}00 0 -g | ./advance_time`) + greg1=${g[0]} + let greg2=greg1+1 + + echo starting AIRS obs merge ${cyear}${cmonth}${cday} + echo gregorian: $greg + + # all of todays data plus the first 40 of tomorrows + ls AIRS.${cyear}.${cmonth}.${cday}.*.out > olist + ls AIRS.${nyear}.${nmonth}.${nday}.0[0123]?.out >> olist + + sed -e "s/YYYY/${cyear}/g" \ + -e "s/MM/${cmonth}/g" \ + -e "s/DD/${cday}/g" \ + -e "s/GREG1/${greg1}/g" \ + -e "s/GREG2/${greg2}/g" < ./input.nml.template > input.nml + + # do the merge here + ./obs_sequence_tool + + + # advance the day; the output is YYYYMMDD00 + curday=nextday + nextday=(`echo ${year}${month}${day}00 +1d | ./advance_time`) + + # advance the loop counter + let d=d+1 + +done + +exit 0 + Property changes on: DART/trunk/observations/AIRS/shell_scripts/mergeit.sh ___________________________________________________________________ Name: svn:executable + * Added: DART/trunk/observations/AIRS/shell_scripts/oneday_down.sh =================================================================== --- DART/trunk/observations/AIRS/shell_scripts/oneday_down.sh (rev 0) +++ DART/trunk/observations/AIRS/shell_scripts/oneday_down.sh 2009-08-27 20:19:52 UTC (rev 4019) @@ -0,0 +1,113 @@ +#!/bin/bash + +# this version gets the tar file from the mass store first. +# unpack one day of tar files at a time, convert them into +# individual obs_seq files. this program also does the merge +# of the 240 individual daily swaths into a single obs_seq file. + +# this program should be started from the work directory. +# it assumes ../data, ../tars, the output dir, etc +# exist relative to starting from AIRS/work. + +# set the first and last days to be converted. can roll over +# month and year boundaries now! +let start_year=2006 +let start_month=10 +let start_day=1 + +let end_year=2007 +let end_month=1 +let end_day=31 + +# relative to work dir +output_dir=../output.thin + +# whether to download the tar file from the mass store or not +# set to one of: true or false +download=true + +# end of things you should have to set in this script + +# convert the start and stop times to gregorian days, so we can +# compute total number of days including rolling over month and +# year boundaries. make sure all values have leading 0s if they +# are < 10. do the end time first so we can use the same values +# to set the initial day while we are doing the total day calc. +mon2=`printf %02d $end_month` +day2=`printf %02d $end_day` +end_d=(`echo ${end_year}${mon2}${day2}00 0 -g | ./advance_time`) + +mon2=`printf %02d $start_month` +day2=`printf %02d $start_day` +start_d=(`echo ${start_year}${mon2}${day2}00 0 -g | ./advance_time`) + +curday=(`echo ${start_year}${mon2}${day2}00 0 | ./advance_time`) + +# how many total days are going to be converted (for the loop counter) +let totaldays=${end_d[0]}-${start_d[0]}+1 + +# loop over each day +let d=1 +while (( d <= totaldays)) ; do + + # parse out the parts from a string which is YYYYMMDDHH + year=${curday:0:4} + month=${curday:4:2} + day=${curday:6:2} + + # compute the equivalent gregorian day here. + g=(`echo ${year}${month}${day}00 0 -g | ./advance_time`) + greg=${g[0]} + + echo starting AIRS to obs ${year}${month}${day} + echo gregorian: $greg + + # download the tar file from the mss first + if [[ "$download" = "true" ]]; then + echo getting ${year}${month}${day}.tar from mass store + (cd ../tars; msrcp mss:/MIJEONG/AIRS/V5/L2/${year}${month}/${year}${month}${day}.tar . ) + fi + + # assume the original collection of data (hdf files, one per swath) + # are in ../tars and that the filenames inside the tar files are named + # YYYYMM/YYYYMMDD/*.hdf + (cd ../data; tar -xvf ../tars/${year}${month}${day}.tar >> tarlog) + + # construct the input list of files for the converter. + # cd there first in a subshell so the ls just contains simple file names + (cd ../data/${year}${month}/${year}${month}${day}; ls AIR*hdf > flist) + + # get back to work dir and edit a template file to set the + # values that change in the namelists. + sed -e "s/YYYY/${year}/g" \ + -e "s/MM/${month}/g" \ + -e "s/DD/${day}/g" \ + -e "s/GREG/${greg}/g" < ./input.nml.template > input.nml + + # actually make the obs_seq files, one per input. these still need to + # be merged if you want daily files. + ./convert_airs_L2 + + # do the merge now + ls ${output_dir}/AIRS.${year}.${month}.${day}.*.out > olist + ./obs_sequence_tool + + # start local mods + # ok, this is a local mod - to try to keep from running out of disk space + remote_dir=/gpfs/ptmp/dart/Obs_sets/AIRS_24_subx4_ascii/${year}${month}/ + cp -f ${output_dir}/AIRS.${year}${month}${day}.out $remote_dir + # and clean up so we don't run out of disk space + (cd ../data/${year}${month}/${year}${month}${day}; rm AIR*hdf) + (cd ${output_dir}; rm AIRS.${year}.${month}.${day}.*.out) + (cd ../tars; rm ${year}${month}${day}.tar) + # end local mods + + # advance the day; the output is YYYYMMDD00 + curday=(`echo ${year}${month}${day}00 +1d | ./advance_time`) + + # advance the loop counter + let d=d+1 + +done + +exit 0 Property changes on: DART/trunk/observations/AIRS/shell_scripts/oneday_down.sh ___________________________________________________________________ Name: svn:executable + * From nancy at ucar.edu Thu Aug 27 17:19:21 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Thu, 27 Aug 2009 17:19:21 -0600 (MDT) Subject: [Dart-dev] [4020] DART/trunk/models/POP: The grid information is not in the LANL-POP restart file, so it must be Message-ID: <200908272319.n7RNJLZ8022210@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090827/20731766/attachment-0001.html -------------- next part -------------- Modified: DART/trunk/models/POP/README =================================================================== --- DART/trunk/models/POP/README 2009-08-27 20:19:52 UTC (rev 4019) +++ DART/trunk/models/POP/README 2009-08-27 23:19:20 UTC (rev 4020) @@ -6,6 +6,8 @@ Tim + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + (this should stay in the README. at some point we might want to move the test program to a separate test directory, in which case this file needs to be updated to reflect that.) @@ -18,3 +20,39 @@ http://www.image.ucar.edu/pub/DART/POP/ nancy + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tim : Tue Jul 21 17:45:52 MDT 2009 + +Working on reading the BINARY grid files instead of the (nonexistent) +netCDF ones. Getting grid sizes from restart netCDF file and must make +hard assumptions about variable storage order. + +dart_pop_mod is being modified to read the pop_in namelist and then set things +like the ocean dynamics timestep. Must ensure that the model_mod then uses that +to set a valid adv_to_time ... + +dart_pop_mod must also set the time_manager_nml:stop_count (and stop_option) to +the right values. + +dart_pop_mod must also create a pointer file with the expected restart file as +a way to make sure the model has advanced to the proper spot. + +advance_model.csh must paste the pop_in.DART namelist on top of the pop_in namelist +for model control ... + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is how I understand (LANL) POP to work: + +Given: +&init_ts_nml + init_ts_option = 'restart' + init_ts_file = 'pop.r' + init_ts_file_fmt = 'nc' +/ + +The init_ts_file entry is completely ignored. A pointer file with the name +"pop_pointer.restart" contains the name of the restart file. + Modified: DART/trunk/models/POP/dart_pop_mod.f90 =================================================================== --- DART/trunk/models/POP/dart_pop_mod.f90 2009-08-27 20:19:52 UTC (rev 4019) +++ DART/trunk/models/POP/dart_pop_mod.f90 2009-08-27 23:19:20 UTC (rev 4020) @@ -11,307 +11,629 @@ ! $Revision$ ! $Date$ -use types_mod, only : r8, rad2deg, PI -use obs_def_mod, only : obs_def_type, get_obs_def_time, read_obs_def, & - write_obs_def, destroy_obs_def, interactive_obs_def, & - copy_obs_def, set_obs_def_time, set_obs_def_kind, & - set_obs_def_error_variance, set_obs_def_location -use time_manager_mod, only : time_type, get_date, set_time, GREGORIAN, & - set_date, set_calendar_type, get_time, & - print_date, print_time, operator(==) +use types_mod, only : r8, rad2deg, PI, SECPERDAY +use time_manager_mod, only : time_type, get_date, set_date, get_time, set_time, & + set_calendar_type, get_calendar_string, & + print_date, print_time, operator(==), operator(-) use utilities_mod, only : get_unit, open_file, close_file, file_exist, & - register_module, error_handler, & - E_ERR, E_MSG, timestamp -use location_mod, only : location_type, set_location, VERTISHEIGHT, VERTISSURFACE -use obs_sequence_mod, only : init_obs_sequence, init_obs, insert_obs_in_seq, & - set_obs_values, set_qc, obs_sequence_type, obs_type, & - copy_obs, set_copy_meta_data, set_qc_meta_data, set_obs_def, & - get_first_obs, get_last_obs, get_obs_def + register_module, error_handler, nc_check, & + find_namelist_in_file, check_namelist_read, & + E_ERR, E_MSG, timestamp, find_textfile_dims, & + logfileunit -use obs_kind_mod, only : get_obs_kind_index +use typesizes +use netcdf implicit none private -public :: real_obs_sequence +public :: get_pop_calendar, set_model_time_step, & + get_horiz_grid_dims, get_vert_grid_dim, & + read_horiz_grid, read_topography, read_vert_grid, & + write_pop_namelist ! version controlled file description for error handling, do not edit character(len=128), parameter :: & - source = "$URL$", & - revision = "$Revision$", & - revdate = "$Date$" + source = '$URL$', & + revision = '$Revision$', & + revdate = '$Date$' +character(len=256) :: msgstring logical, save :: module_initialized = .false. +character(len=256) :: ic_filename, restart_filename + ! set this to true if you want to print out the current time ! after each N observations are processed, for benchmarking. logical :: print_timestamps = .false. integer :: print_every_Nth = 10000 -contains +!------------------------------------------------------------------ +! The POP time manager namelist variables +!------------------------------------------------------------------ -!------------------------------------------------- +character(len=100) :: accel_file ! length consistent with POP +character(len= 64) :: stop_option, runid, dt_option, time_mix_opt +character(len= 1) :: date_separator +logical :: impcor, laccel, allow_leapyear +real(r8) :: dtuxcel, dt_count +integer :: iyear0, imonth0, iday0, ihour0, iminute0, isecond0 +integer :: stop_count, fit_freq, time_mix_freq -function real_obs_sequence (obsfile, year, month, day, max_num, & - lon1, lon2, lat1, lat2) -!------------------------------------------------------------------------------ -! this function is to prepare data to DART sequence format +namelist /time_manager_nml/ runid, time_mix_opt, time_mix_freq, & + impcor, laccel, accel_file, dtuxcel, iyear0, imonth0, & + iday0, ihour0, iminute0, isecond0, dt_option, dt_count, & + stop_option, stop_count, date_separator, allow_leapyear, fit_freq + +!------------------------------------------------------------------ +! The POP restart manager namelist variables +!------------------------------------------------------------------ + +character(len=100) :: restart_outfile ! length consistent with POP +character(len= 64) :: restart_freq_opt, restart_fmt +logical :: leven_odd_on, pressure_correction +integer :: restart_freq, even_odd_freq + +namelist /restart_nml/ restart_freq_opt, restart_freq, restart_outfile, & + restart_fmt, leven_odd_on, even_odd_freq, pressure_correction + +!------------------------------------------------------------------ +! The POP initial temperature and salinity namelist +!------------------------------------------------------------------ + +character(len=100) :: init_ts_file ! length consistent with POP +character(len= 64) :: init_ts_option, init_ts_file_fmt + +namelist /init_ts_nml/ init_ts_option, init_ts_file, init_ts_file_fmt + +!------------------------------------------------------------------ +! The POP domain namelist +!------------------------------------------------------------------ + +character(len= 64) :: clinic_distribution_type, tropic_distribution_type +character(len= 64) :: ew_boundary_type, ns_boundary_type +integer :: nprocs_clinic, nprocs_tropic + +namelist /domain_nml/ clinic_distribution_type, nprocs_clinic, & + tropic_distribution_type, nprocs_tropic, & + ew_boundary_type, ns_boundary_type + +!------------------------------------------------------------------ +! The POP grid info namelist +!------------------------------------------------------------------ ! -character(len=129), intent(in) :: obsfile -integer, intent(in) :: year, month, day, max_num -real(r8), intent(in) :: lon1, lon2, lat1, lat2 +! POP grid information comes in several files: +! horizontal grid lat/lons in one, +! topography (lowest valid vert level) in another, and +! the vertical grid spacing in a third. +! +!------------------------------------------------------------------ +! +! Here is what we can get from the (binary) horiz grid file: +! real (r8), dimension(:,:), allocatable :: & +! ULAT, &! latitude (radians) of U points +! ULON, &! longitude (radians) of U points +! HTN , &! length (cm) of north edge of T box +! HTE , &! length (cm) of east edge of T box +! HUS , &! length (cm) of south edge of U box +! HUW , &! length (cm) of west edge of U box +! ANGLE ! angle +! +! Here is what we can get from the topography file: +! integer, dimension(:,:), allocatable :: & +! KMT ! k index of deepest grid cell on T grid +! +! These must be derived or come from someplace else ... +! KMU ! k index of deepest grid cell on U grid +! HT ! real(r8) value of deepest valid T depth (in cm) +! HU ! real(r8) value of deepest valid U depth (in cm) +! +! The vert grid file is ascii, with 3 columns/line: +! cell thickness(in cm) cell center(in m) cell bottom(in m) +! +!------------------------------------------------------------------ -type(obs_sequence_type) :: real_obs_sequence +character(len=100) :: horiz_grid_file, vert_grid_file, topography_file, & + bottom_cell_file, region_mask_file +character(len= 64) :: horiz_grid_opt, sfc_layer_opt, vert_grid_opt, & + topography_opt +logical :: partial_bottom_cells, topo_smooth, flat_bottom, lremove_points +namelist /grid_nml/ horiz_grid_opt, horiz_grid_file, sfc_layer_opt, & + vert_grid_opt, vert_grid_file, topography_opt, topography_file, & + partial_bottom_cells, bottom_cell_file, region_mask_file, & + topo_smooth, flat_bottom, lremove_points -type(obs_def_type) :: obs_def -type(obs_type) :: obs, prev_obs -integer :: i, num_copies, num_qc -integer :: days, seconds -integer :: yy, mn, dd, hh, mm, ss -integer :: startdate1, startdate2 -integer :: obs_num, calender_type, iskip -integer :: obs_unit -integer :: which_vert, obstype +!====================================================================== +contains +!====================================================================== -real (r8) :: lon, lat, vloc, obs_value -real (r8) :: aqc, var2, lonc -type(time_type) :: time, pre_time -character(len = 32) :: obs_kind_name -character(len = 80) :: label -character(len = 129) :: copy_meta_data, qc_meta_data +subroutine initialize_module +!------------------------------------------------------------------ +integer :: iunit, io -if ( .not. module_initialized ) call initialize_module +! Read POP calendar information +! In 'restart' mode, this is primarily the calendar type and 'stop' +! information. The time attributes of the restart file override +! the namelist time information. -num_copies = 1 -num_qc = 1 +call find_namelist_in_file('pop_in', 'time_manager_nml', iunit) +read(iunit, nml = time_manager_nml, iostat = io) +call check_namelist_read(iunit, io, 'time_manager_nml') -! Initialize an obs_sequence +if ( allow_leapyear ) then + call set_calendar_type('gregorian') +else + call set_calendar_type('noleap') +endif -call init_obs_sequence(real_obs_sequence, num_copies, num_qc, max_num) +! Read POP initial information (for input/restart filename) +! The tricky part here is that we should really check for +! the existence of the init_ts_file and take evasive action +! like checking for the existence of a pointer file. -! set meta data of obs_seq +call find_namelist_in_file('pop_in', 'init_ts_nml', iunit) +read(iunit, nml = init_ts_nml, iostat = io) +call check_namelist_read(iunit, io, 'init_ts_nml') -do i = 1, num_copies - copy_meta_data = 'observation' - call set_copy_meta_data(real_obs_sequence, i, copy_meta_data) -end do +ic_filename = trim(init_ts_file)//'.'//trim(init_ts_file_fmt) -do i = 1, num_qc - qc_meta_data = 'QC index' - call set_qc_meta_data(real_obs_sequence, i, qc_meta_data) -end do +! FIXME ... what about the pointer file ... +if ( .not. file_exist(ic_filename) ) then + msgstring = 'pop_in:init_ts_file '//trim(ic_filename)//' not found' + call error_handler(E_ERR,'initialize_module', & + msgstring, source, revision, revdate) +endif -! Initialize the obs variable +! Read POP restart information (for model timestepping/grid dimensions) +call find_namelist_in_file('pop_in', 'restart_nml', iunit) +read(iunit, nml = restart_nml, iostat = io) +call check_namelist_read(iunit, io, 'restart_nml') -call init_obs(obs, num_copies, num_qc) -call init_obs(prev_obs, num_copies, num_qc) +! Read POP domain information (for lon wrapping or not) +call find_namelist_in_file('pop_in', 'domain_nml', iunit) +read(iunit, nml = domain_nml, iostat = io) +call check_namelist_read(iunit, io, 'domain_nml') -! set observation time type -calender_type = GREGORIAN -call set_calendar_type(calender_type) +! Read POP grid information (for grid dims/filenames) +call find_namelist_in_file('pop_in', 'grid_nml', iunit) +read(iunit, nml = grid_nml, iostat = io) +call check_namelist_read(iunit, io, 'grid_nml') -! open observation data file +module_initialized = .true. -obs_unit = get_unit() -open(unit = obs_unit, file = obsfile, form='formatted', status='old') -print*, 'input file opened= ', trim(obsfile) -rewind (obs_unit) +! Print module information to log file and stdout. +call register_module(source, revision, revdate) -obs_num = 0 -iskip = 0 +end subroutine initialize_module -! loop over all observations within the file -!------------------------------------------------------------------------------ -obsloop: do - read(obs_unit,*,end=200) lon, lat, vloc, obs_value, which_vert, var2, aqc, & - obs_kind_name, startdate1, startdate2 +subroutine get_horiz_grid_dims(Nx, Ny) +!------------------------------------------------------------------ +! subroutine get_horiz_grid_dims(Nx, Ny) +! +! Read the lon, lat grid size from the restart netcdf file. +! The actual grid file is a binary file with no header information. +! +! The file name comes from module storage ... namelist. - !print*,'' - !print*,' Observation ', obs_num+1 - !print*,' lon lat vloc obs_value ',lon, lat, vloc, obs_value - !print*,' which_vert var2 aqc ',which_vert, var2, aqc - !print*,' obs_kind_name ',obs_kind_name - !print*,' date1 date2 ',startdate1, startdate2 +integer, intent(out) :: Nx ! Number of Longitudes +integer, intent(out) :: Ny ! Number of Latitudes - ! Calculate the DART time from the observation time - yy = startdate1/10000 - mn = mod(startdate1/100,100) - dd = mod(startdate1 ,100) - hh = startdate2/10000 - mm = mod(startdate2/100,100) - ss = mod(startdate2 ,100) - time = set_date(yy,mn,dd,hh,mm,ss) - call get_time(time,seconds,days) +integer :: grid_id, dimid, nc_rc - ! verify the location is not outside valid limits - if((lon > 360.0_r8) .or. (lon < 0.0_r8) .or. & - (lat > 90.0_r8) .or. (lat < -90.0_r8)) then - write(*,*) 'invalid location. lon,lat = ', lon, lat - iskip = iskip + 1 - cycle obsloop - endif +if ( .not. module_initialized ) call initialize_module - lonc = lon - if (lon2 > 360.0_r8 .and. lon < 180.0_r8) lonc = lon + 360.0_r8 +! get the ball rolling ... - ! reject observations outside the bounding box - if(lat < lat1 .or. lat > lat2 .or. lonc < lon1 .or. lonc > lon2) then - iskip = iskip + 1 - cycle obsloop +call nc_check(nf90_open(trim(ic_filename), nf90_nowrite, grid_id), & + 'get_horiz_grid_dims','open '//trim(ic_filename)) + +! Longitudes : get dimid for 'i' or 'nlon', and then get value +nc_rc = nf90_inq_dimid(grid_id, 'i', dimid) +if (nc_rc /= nf90_noerr) then + nc_rc = nf90_inq_dimid(grid_id, 'nlon', dimid) + if (nc_rc /= nf90_noerr) then + msgstring = "unable to find either 'i' or 'nlon' in file "//trim(ic_filename) + call error_handler(E_ERR, 'get_horiz_grid_dims', msgstring, & + source,revision,revdate) endif +endif - ! assign each observation the correct observation type - obstype = get_obs_kind_index(obs_kind_name) - if(obstype < 1) then - print*, 'unknown observation type [',trim(obs_kind_name),'] ... skipping ...' - cycle obsloop - !else - ! print*,trim(obs_kind_name),' is ',obstype +call nc_check(nf90_inquire_dimension(grid_id, dimid, len=Nx), & + 'get_horiz_grid_dims','inquire_dimension i '//trim(ic_filename)) + +! Latitudes : get dimid for 'j' or 'nlat' ... and then get value +nc_rc = nf90_inq_dimid(grid_id, 'j', dimid) +if (nc_rc /= nf90_noerr) then + nc_rc = nf90_inq_dimid(grid_id, 'nlat', dimid) + if (nc_rc /= nf90_noerr) then + msgstring = "unable to find either 'j' or 'nlat' in "//trim(ic_filename) + call error_handler(E_ERR, 'get_horiz_grid_dims', msgstring, & + source,revision,revdate) endif +endif - obs_num = obs_num + 1 +call nc_check(nf90_inquire_dimension(grid_id, dimid, len=Ny), & + 'get_horiz_grid_dims','inquire_dimension i '//trim(ic_filename)) - ! print a reassuring message after every Nth processed obs. - ! if requested, print in the form of a timestamp. - ! the default is just a plain string with the current obs count. - if(mod(obs_num, print_every_Nth) == 0) then - write(label, *) 'obs count = ', obs_num - if (print_timestamps) then - call timestamp(string1=label, pos='') - else - write(*,*) trim(label) - endif - endif - if(obs_num == max_num) then - print*, 'Max limit for observation count reached. Increase value in namelist' - stop - endif +! tidy up + +call nc_check(nf90_close(grid_id), & + 'get_horiz_grid_dims','close '//trim(ic_filename) ) + +end subroutine get_horiz_grid_dims + + + + subroutine get_vert_grid_dim(Nz) +!------------------------------------------------------------------ +! subroutine get_vert_grid_dim(Nz) +! +! count the number of lines in the ascii file to figure out max +! number of vert blocks. + +integer, intent(out) :: Nz + +integer :: linelen ! disposable + +if ( .not. module_initialized ) call initialize_module + +call find_textfile_dims(vert_grid_file, Nz, linelen) + +end subroutine get_vert_grid_dim + + -! create the obs_def for this observation, add to sequence -!------------------------------------------------------------------------------ - - call real_obs(num_copies, num_qc, obs, lon, lat, vloc, obs_value, & - var2, aqc, obstype, which_vert, seconds, days) - - if(obs_num == 1) then ! for the first observation +subroutine get_pop_calendar(calstring) +!------------------------------------------------------------------ +! the initialize_module ensures that the pop namelists are read and +! the DART time manager gets the pop calendar setting. +! +! Then, the DART time manager is queried to return what it knows ... +! +character(len=*), INTENT(OUT) :: calstring - call insert_obs_in_seq(real_obs_sequence, obs) - call copy_obs(prev_obs, obs) - pre_time = time +if ( .not. module_initialized ) call initialize_module - else ! not the first observation +call get_calendar_string(calstring) - if(time == pre_time) then ! same time as previous observation +end subroutine get_pop_calendar - call insert_obs_in_seq(real_obs_sequence, obs, prev_obs) - call copy_obs(prev_obs, obs) - pre_time = time - else ! not the same time - call insert_obs_in_seq(real_obs_sequence, obs) - call copy_obs(prev_obs, obs) - pre_time = time +function set_model_time_step() +!------------------------------------------------------------------ +! the initialize_module ensures that the pop namelists are read. +! The restart times in the pop_in&restart_nml are used to define +! appropriate assimilation timesteps. +! +type(time_type) :: set_model_time_step - endif +if ( .not. module_initialized ) call initialize_module - endif +! Check the 'restart_freq_opt' and 'restart_freq' to determine +! when we can stop the model -end do obsloop +if ( trim(restart_freq_opt) == 'nday' ) then + set_model_time_step = set_time(0, restart_freq) ! (seconds, days) +else + call error_handler(E_ERR,'set_model_time_step', & + 'restart_freq_opt must be days', source, revision, revdate) +endif -200 continue +end function set_model_time_step -close(obs_unit) -! Print a little summary -print*, 'obs used = ', obs_num, ' obs skipped = ', iskip -if ( get_first_obs(real_obs_sequence, obs) ) then - call get_obs_def(obs, obs_def) - pre_time = get_obs_def_time(obs_def) - call print_time(pre_time,' first time in sequence is ') - call print_date(pre_time,' first date in sequence is ') + +subroutine write_pop_namelist(model_time, adv_to_time) +!------------------------------------------------------------------ +! +type(time_type), INTENT(IN) :: model_time, adv_to_time +type(time_type) :: offset + +integer :: iunit, secs, days + +if ( .not. module_initialized ) call initialize_module + +offset = adv_to_time - model_time +call get_time(offset, secs, days) + +if (secs /= 0 ) then + write(msgstring,*)'adv_to_time has seconds == ',secs,' must be zero' + call error_handler(E_ERR,'write_pop_namelist', msgstring, source, revision, revdate) endif -if( get_last_obs(real_obs_sequence, obs)) then - call get_obs_def(obs, obs_def) - time = get_obs_def_time(obs_def) - call print_time(time,' last time in sequence is ') - call print_date(time,' last date in sequence is ') + +! call print_date( model_time,'write_pop_namelist:dart model date') +! call print_date(adv_to_time,'write_pop_namelist:advance_to date') +! call print_time( model_time,'write_pop_namelist:dart model time') +! call print_time(adv_to_time,'write_pop_namelist:advance_to time') +! call print_time( offset,'write_pop_namelist:a distance of') +! write( *,'(''write_pop_namelist:TIME_MANAGER_NML STOP_COUNT '',i10,'' days'')') days + +!Convey the information to the namelist 'stop option' and 'stop count' + +if ( trim(stop_option) == 'nday' ) then + stop_count = days +else + call error_handler(E_ERR,'write_pop_namelist', & + 'stop_option must be "nday"', source, revision, revdate) endif -print*, '' -end function real_obs_sequence +iunit = open_file('pop_in.DART',form='formatted',action='rewind') +write(iunit, nml=time_manager_nml) +write(iunit, '('' '')') +close(iunit) +end subroutine write_pop_namelist -subroutine real_obs(num_copies, num_qc, obs, lon, lat, vloc, obs_value, & - var2, aqc, obs_kind, which_vert, seconds, days) -!------------------------------------------------------------------------------ -integer, intent(in) :: num_copies, num_qc -type(obs_type), intent(inout) :: obs -real(r8), intent(in) :: lon, lat, vloc, obs_value, var2, aqc -integer, intent(in) :: obs_kind, which_vert, seconds, days -integer :: i -real(r8) :: aqc01(1), obs_value01(1) -type(obs_def_type) :: obsdef0 + subroutine read_horiz_grid(nx, ny, ULAT, ULON, TLAT, TLON) +!------------------------------------------------------------------ +! subroutine read_horiz_grid(nx, ny, ULAT, ULON, TLAT, TLON) +! +! Open and read the binary grid file +integer, intent(in) :: nx, ny +real(r8), dimension(nx,ny), intent(out) :: ULAT, ULON, TLAT, TLON + +!real(r8), dimension(nx,ny) :: & +! HTN , &! length (cm) of north edge of T box +! HTE , &! length (cm) of east edge of T box +! HUS , &! length (cm) of south edge of U box +! HUW , &! length (cm) of west edge of U box +! ANGLE ! angle + +integer :: grid_unit, reclength + if ( .not. module_initialized ) call initialize_module -! Does real initialization of an observation type +! Check to see that the file exists. -call real_obs_def(obsdef0, lon, lat, vloc, & - var2, obs_kind, which_vert, seconds, days) -call set_obs_def(obs, obsdef0) +if ( .not. file_exist(horiz_grid_file) ) then + msgstring = 'pop_in:horiz_grid_file '//trim(horiz_grid_file)//' not found' + call error_handler(E_ERR,'read_horiz_grid', & + msgstring, source, revision, revdate) +endif -do i = 1, num_copies - obs_value01(1) = obs_value - call set_obs_values(obs, obs_value01(1:1) ) +! Open it and read them in the EXPECTED order. +! Actually, we only need the first two, so I'm skipping the rest. + +grid_unit = get_unit() +INQUIRE(iolength=reclength) ULAT + +open(grid_unit, file=trim(horiz_grid_file), form='unformatted', & + access='direct', recl=reclength, status='old' ) +read(grid_unit, rec=1) ULAT +read(grid_unit, rec=2) ULON +!read(grid_unit, rec=3) HTN +!read(grid_unit, rec=4) HTE +!read(grid_unit, rec=5) HUS +!read(grid_unit, rec=6) HUW +!read(grid_unit, rec=7) ANGLE +close(grid_unit) + +call calc_tpoints(nx, ny, ULAT, ULON, TLAT, TLON) + +! convert from radians to degrees + +ULAT = ULAT * rad2deg +ULON = ULON * rad2deg +TLAT = TLAT * rad2deg +TLON = TLON * rad2deg + +! ensure [0,360) [-90,90] + +where (ULON < 0.0_r8) ULON = ULON + 360.0_r8 +where (ULON > 360.0_r8) ULON = ULON - 360.0_r8 +where (TLON < 0.0_r8) TLON = TLON + 360.0_r8 +where (TLON > 360.0_r8) TLON = TLON - 360.0_r8 + +where (ULAT < -90.0_r8) ULAT = -90.0_r8 +where (ULAT > 90.0_r8) ULAT = 90.0_r8 +where (TLAT < -90.0_r8) TLAT = -90.0_r8 +where (TLAT > 90.0_r8) TLAT = 90.0_r8 + +end subroutine read_horiz_grid + + + subroutine calc_tpoints(nx, ny, ULAT, ULON, TLAT, TLON) +!------------------------------------------------------------------ +! subroutine calc_tpoints(nx, ny, ULAT, ULON, TLAT, TLON) +! +! mimic POP grid.F90:calc_tpoints(), but for one big block. + +integer, intent( in) :: nx, ny +real(r8), dimension(nx,ny), intent( in) :: ULAT, ULON +real(r8), dimension(nx,ny), intent(out) :: TLAT, TLON + +integer :: i, j +real(r8) :: xc,yc,zc,xs,ys,zs,xw,yw,zw ! Cartesian coordinates for +real(r8) :: xsw,ysw,zsw,tx,ty,tz,da ! nbr points + +real(r8), parameter :: c0 = 0.000_r8, c1 = 1.000_r8 +real(r8), parameter :: c2 = 2.000_r8, c4 = 4.000_r8 +real(r8), parameter :: p25 = 0.250_r8, p5 = 0.500_r8 +real(r8) :: pi, pi2, pih, radian + +if ( .not. module_initialized ) call initialize_module + +! Define some constants as in pop + +pi = c4*atan(c1) +pi2 = c2*pi +pih = p5*pi +radian = 180.0_r8/pi + +do j=2,ny +do i=2,nx + + !*** convert neighbor U-cell coordinates to 3-d Cartesian coordinates + !*** to prevent problems with averaging near the pole + + zsw = cos(ULAT(i-1,j-1)) + xsw = cos(ULON(i-1,j-1))*zsw + ysw = sin(ULON(i-1,j-1))*zsw + zsw = sin(ULAT(i-1,j-1)) + + zs = cos(ULAT(i ,j-1)) + xs = cos(ULON(i ,j-1))*zs + ys = sin(ULON(i ,j-1))*zs + zs = sin(ULAT(i ,j-1)) + + zw = cos(ULAT(i-1,j )) + xw = cos(ULON(i-1,j ))*zw + yw = sin(ULON(i-1,j ))*zw + zw = sin(ULAT(i-1,j )) + + zc = cos(ULAT(i ,j )) + xc = cos(ULON(i ,j ))*zc + yc = sin(ULON(i ,j ))*zc + zc = sin(ULAT(i ,j )) + + !*** straight 4-point average to T-cell Cartesian coords + + tx = p25*(xc + xs + xw + xsw) + ty = p25*(yc + ys + yw + ysw) + tz = p25*(zc + zs + zw + zsw) + + !*** convert to lat/lon in radians + + da = sqrt(tx**2 + ty**2 + tz**2) + + TLAT(i,j) = asin(tz/da) + + if (tx /= c0 .or. ty /= c0) then + TLON(i,j) = atan2(ty,tx) + else + TLON(i,j) = c0 + endif + end do +end do -do i = 1, num_qc - aqc01(1) = aqc - call set_qc(obs, aqc01(1:1)) +!*** for bottom row of domain where sw 4pt average is not valid, +!*** extrapolate from interior +!*** NOTE: THIS ASSUMES A CLOSED SOUTH BOUNDARY - WILL NOT +!*** WORK CORRECTLY FOR CYCLIC OPTION + +do i=1,nx + TLON(i,1) = TLON(i,1+1) + TLAT(i,1) = c2*TLAT(i,1+1) - TLAT(i,1+2) end do -end subroutine real_obs +where (TLON(:,:) > pi2) TLON(:,:) = TLON(:,:) - pi2 +where (TLON(:,:) < c0 ) TLON(:,:) = TLON(:,:) + pi2 +!*** this leaves the leftmost/western edge to be filled +!*** if the longitudes wrap, this is easy. +!*** the gx3v5 grid TLON(:,2) and TLON(:,nx) are both about 2pi, +!*** so taking the average is reasonable. +!*** averaging the latitudes is always reasonable. +if ( trim(ew_boundary_type) == 'cyclic' ) then -subroutine real_obs_def(obs_def, lon, lat, vloc, & - var2, obs_kind, which_vert, seconds, days) -!---------------------------------------------------------------------- -type(obs_def_type), intent(inout) :: obs_def -real(r8),intent(in) :: lon, lat, vloc, var2 -integer, intent(in) :: obs_kind, which_vert, seconds, days + TLAT(1,:) = (TLAT(2,:) + TLAT(nx,:))/c2 + TLON(1,:) = (TLON(2,:) + TLON(nx,:))/c2 -type(location_type) :: loc0 +else + write(msgstring,'(''pop_in&domain_nml:ew_boundary_type '',a,'' unknown.'')') & + trim(ew_boundary_type) + call error_handler(E_ERR,'calc_tpoints',msgstring,source,revision,revdate) +endif +end subroutine calc_tpoints + + + + subroutine read_topography(nx, ny, KMT, KMU) +!------------------------------------------------------------------ +! subroutine read_topography(nx, ny, KMT, KMU) +! +! Open and read the binary topography file + +integer, intent(in) :: nx, ny +integer, dimension(nx,ny), intent(out) :: KMT, KMU + +integer :: i, j, topo_unit, reclength + if ( .not. module_initialized ) call initialize_module -! set obs location -loc0 = set_location(lon, lat, vloc, which_vert ) -call set_obs_def_location(obs_def, loc0) +! Check to see that the file exists. -! set obs kind -call set_obs_def_kind(obs_def, obs_kind) +if ( .not. file_exist(topography_file) ) then + msgstring = 'pop_in:topography_file '//trim(topography_file)//' not found' + call error_handler(E_ERR,'read_topography', & + msgstring, source, revision, revdate) +endif -call set_obs_def_time(obs_def, set_time(seconds, days) ) -call set_obs_def_error_variance(obs_def, var2) +! read the binary file -end subroutine real_obs_def +topo_unit = get_unit() +INQUIRE(iolength=reclength) KMT +open( topo_unit, file=trim(topography_file), form='unformatted', & + access='direct', recl=reclength, status='old' ) +read( topo_unit, rec=1) KMT +close(topo_unit) +KMU(1, 1) = 0 +do j=2,ny +do i=2,nx + KMU(i,j) = min(KMT(i, j), KMT(i-1, j), KMT(i, j-1), KMT(i-1, j-1)) +enddo +enddo -subroutine initialize_module -!------------------------------------------------- -call register_module(source, revision, revdate) -module_initialized = .true. -end subroutine initialize_module +end subroutine read_topography + + subroutine read_vert_grid(nz, ZC, ZG) +!------------------------------------------------------------------ +! subroutine read_vert_grid(nz, ZC, ZG) +! +! Open and read the ASCII vertical grid information +! +! The vert grid file is ascii, with 3 columns/line: +! cell thickness(in cm) cell center(in m) cell bottom(in m) + +integer, intent(in) :: nz +real(r8), intent(out) :: ZC(nz), ZG(nz) + +integer :: iunit, i, ios +real(r8) :: depth + +if ( .not. module_initialized ) call initialize_module + +! Check to see that the file exists. + +if ( .not. file_exist(vert_grid_file) ) then + msgstring = 'pop_in:vert_grid_file '//trim(vert_grid_file)//' not found' + call error_handler(E_ERR,'read_vert_grid', & + msgstring, source, revision, revdate) +endif + +! read the ASCII file + +iunit = open_file(trim(vert_grid_file), action = 'read') + +do i=1, nz + + read(iunit,*,iostat=ios) depth, ZC(i), ZG(i) + + if ( ios /= 0 ) then ! error + write(msgstring,*)'error reading depths, line ',i + call error_handler(E_ERR,'read_vert_grid',msgstring,source,revision,revdate) + endif + +enddo + +end subroutine read_vert_grid + + + end module dart_pop_mod Modified: DART/trunk/models/POP/dart_to_pop.f90 =================================================================== --- DART/trunk/models/POP/dart_to_pop.f90 2009-08-27 20:19:52 UTC (rev 4019) +++ DART/trunk/models/POP/dart_to_pop.f90 2009-08-27 23:19:20 UTC (rev 4020) @@ -27,12 +27,13 @@ initialize_utilities, finalize_utilities, & find_namelist_in_file, check_namelist_read, & logfileunit +use assim_model_mod, only : open_restart_read, aread_state_restart, close_restart +use time_manager_mod, only : time_type, get_time, print_time, print_date, & + operator(-), set_time use model_mod, only : static_init_model, sv_to_restart_file, & get_model_size, get_model_time_step, & set_model_end_time -use assim_model_mod, only : open_restart_read, aread_state_restart, close_restart -use time_manager_mod, only : time_type, get_time, print_time, print_date, & - operator(-) +use dart_pop_mod, only : write_pop_namelist implicit none @@ -48,15 +49,16 @@ character (len = 128) :: dart_to_pop_input_file = 'assim_model_state_ic' character (len = 128) :: dart_to_pop_restart_file = 'my_pop_restart_file' +logical :: advance_time_present = .TRUE. -namelist /dart_to_pop_nml/ dart_to_pop_input_file, dart_to_pop_restart_file +namelist /dart_to_pop_nml/ dart_to_pop_input_file, dart_to_pop_restart_file, & + advance_time_present !---------------------------------------------------------------------- integer :: iunit, io, x_size integer :: secs, days type(time_type) :: model_time, adv_to_time -type(time_type) :: model_timestep, offset real(r8), allocatable :: statevector(:) !---------------------------------------------------------------------- @@ -82,52 +84,41 @@ !---------------------------------------------------------------------- iunit = open_restart_read(dart_to_pop_input_file) -call aread_state_restart(model_time, statevector, iunit, adv_to_time) + +if ( advance_time_present ) then + call aread_state_restart(model_time, statevector, iunit, adv_to_time) +else + call aread_state_restart(model_time, statevector, iunit) +endif call close_restart(iunit) !---------------------------------------------------------------------- ! update the current POP state vector -!---------------------------------------------------------------------- - -call sv_to_restart_file(statevector, dart_to_pop_restart_file, & - model_time, adv_to_time) - -!iunit = open_file('data.cal.DART',form='formatted',action='rewind') -!write(iunit, nml=CAL_NML) -!close(iunit) - -!---------------------------------------------------------------------- -! convert the adv_to_time to the appropriate number of POP +! Convey the amount of time to integrate the model ... ! time_manager_nml: stop_option, stop_count increments !---------------------------------------------------------------------- -model_timestep = get_model_time_step() -offset = adv_to_time - model_time +call sv_to_restart_file(statevector, dart_to_pop_restart_file, model_time) -!call set_model_end_time(offset) -!call write_data_namelistfile() +if ( advance_time_present ) then + call write_pop_namelist(model_time, adv_to_time) +endif !---------------------------------------------------------------------- ! Log what we think we're doing, and exit. !---------------------------------------------------------------------- -call get_time(offset, secs, days) - call print_date( model_time,'dart_to_pop:dart model date') -call print_date(adv_to_time,'dart_to_pop:advance_to date') call print_time( model_time,'dart_to_pop:dart model time') -call print_time(adv_to_time,'dart_to_pop:advance_to time') -call print_time( offset,'dart_to_pop:a distance of') -write( * ,'(''dart_to_pop:PARM03 endTime '',i,'' seconds'')') & - (secs + days*SECPERDAY) - call print_date( model_time,'dart_to_pop:dart model date',logfileunit) -call print_date(adv_to_time,'dart_to_pop:advance_to date',logfileunit) call print_time( model_time,'dart_to_pop:dart model time',logfileunit) + +if ( advance_time_present ) then +call print_time(adv_to_time,'dart_to_pop:advance_to time') +call print_date(adv_to_time,'dart_to_pop:advance_to date') call print_time(adv_to_time,'dart_to_pop:advance_to time',logfileunit) -call print_time( offset,'dart_to_pop: a distance of',logfileunit) -write(logfileunit,'(''dart_to_pop:PARM03 endTime '',i,'' seconds'')') & - (secs + days*SECPERDAY) +call print_date(adv_to_time,'dart_to_pop:advance_to date',logfileunit) +endif call finalize_utilities() Modified: DART/trunk/models/POP/matlab/Check_pop_to_dart.m =================================================================== --- DART/trunk/models/POP/matlab/Check_pop_to_dart.m 2009-08-27 20:19:52 UTC (rev 4019) +++ DART/trunk/models/POP/matlab/Check_pop_to_dart.m 2009-08-27 23:19:20 UTC (rev 4020) @@ -1,166 +1,160 @@ -% Check_pop_to_dart +function [dart pop] = Check_pop_to_dart(popfile,dartfile) +% Check_pop_to_dart : check pop_to_dart.f90 ... the conversion of a POP restart to a DART state vector file. % -% data.cal holds the starting time information +% popfile = 'pop.r.nc'; +% dartfile = 'dart.ics'; +% x = Check_pop_to_dart(popfile, dartfile); % +% popfile = '~DART/models/POP/work/cx3.dart.001.pop.r.0002-01-01-00000.nc'; +% dartfile = '~DART/models/POP/work/perfect_ics'; +% [dart pop] = Check_pop_to_dart(popfile, dartfile); -popdir = '/ptmp/thoar/POP/job_40705'; -popfile = 'pop.r.x1A.00000102'; -dartfile = 'assim_model_state_ud'; +% Data Assimilation Research Testbed -- DART +% Copyright 2004-2007, Data Assimilation Research Section +% University Corporation for Atmospheric Research +% Licensed under the GPL -- www.gpl.org/licenses/gpl.html +% +% +% $URL$ +% $Id$ +% $Revision$ +% $Date$ -fname = sprintf('%s/%s',popdir,popfile); +% Read the original POP file values. +if (exist(popfile,'file') ~= 2) + error('POP file %s does not exist.',popfile) +end +if (exist(dartfile,'file') ~= 2) + error('DART file %s does not exist.',dartfile) +end -S = nc_varget(fname, 'SALT_CUR'); -T = nc_varget(fname, 'TEMP_CUR'); -U = nc_varget(fname, 'UVEL_CUR'); -V = nc_varget(fname, 'VVEL_CUR'); -SSH = nc_varget(fname,'PSURF_CUR'); +iyear = nc_attget(popfile,nc_global,'iyear'); +imonth = nc_attget(popfile,nc_global,'imonth'); +iday = nc_attget(popfile,nc_global,'iday'); +ihour = nc_attget(popfile,nc_global,'ihour'); +iminute = nc_attget(popfile,nc_global,'iminute'); +isecond = nc_attget(popfile,nc_global,'isecond'); -modelsize = prod(size(S)) + prod(size(T)) + ... - prod(size(U)) + prod(size(V)) + prod(size(SSH)); +fprintf('POP year month day hour minute second %d %d %d %d %d %d\n', ... + iyear,imonth,iday,ihour,iminute,isecond); -[nx ny nz] = size(S); +% The nc_varget() function returns the variables with the fastest +% varying dimension on the right. This is opposite to the Fortran +% convention of the fastest varying dimension on the left ... so +% one of the variables must be permuted in order to be compared. -iyear = nc_attget(fname,nc_global,'iyear'); -imonth = nc_attget(fname,nc_global,'imonth'); -iday = nc_attget(fname,nc_global,'iday'); -ihour = nc_attget(fname,nc_global,'ihour'); -iminute = nc_attget(fname,nc_global,'iminute'); -isecond = nc_attget(fname,nc_global,'isecond'); +S = nc_varget(popfile, 'SALT_CUR'); pop.S = permute(S, [3 2 1]); +T = nc_varget(popfile, 'TEMP_CUR'); pop.T = permute(T, [3 2 1]); +U = nc_varget(popfile, 'UVEL_CUR'); pop.U = permute(U, [3 2 1]); +V = nc_varget(popfile, 'VVEL_CUR'); pop.V = permute(V, [3 2 1]); +PSURF = nc_varget(popfile, 'PSURF_CUR'); pop.PSURF = permute(PSURF, [2 1]); -fprintf('year month day hour minute second %d %d %d %d %d %d\n', ... - iyear,imonth,iday,ihour,iminute,isecond); +disp(sprintf('pop.PSURF min/max are %0.8g %0.8g',min(pop.PSURF(:)),max(pop.PSURF(:)))) -% Get the dart equivalent +[nx ny nz] = size(pop.U); +fprintf('vert dimension size is %d\n',nz) +fprintf('N-S dimension size is %d\n',ny) +fprintf('E-W dimension size is %d\n',nx) -fname = sprintf('%s/%s',popdir,dartfile); -fid = fopen(fname,'rb','ieee-le'); +modelsize = nx*ny*nz; + +% filesize = S,T,U,V * (nx*ny*nz) + SSH * (nx*ny) +storage = 8; +size2d = nx*ny; +size3d = nx*ny*nz; +n2ditems = 1*size2d; +n3ditems = 4*size3d; +rec1size = 4+(4+4)+4; % time stamps ... +rec2size = 4+(n3ditems*storage + n2ditems*storage)+4; + +fsize = rec1size + rec2size; +disp(sprintf('with a modelsize of %d the file size should be %d bytes', ... + modelsize,fsize)) + +% Open and read timetag for state +fid = fopen(dartfile,'rb','ieee-le'); trec1 = fread(fid,1,'int32'); seconds = fread(fid,1,'int32'); days = fread(fid,1,'int32'); trecN = fread(fid,1,'int32'); @@ Diff output truncated at 40000 characters. @@ From nancy at ucar.edu Fri Aug 28 09:10:45 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Fri, 28 Aug 2009 09:10:45 -0600 (MDT) Subject: [Dart-dev] [4021] DART/trunk/observations/AIRS/work/path_names_advance_time: Fix the name of the utilities_mod file. Message-ID: <200908281510.n7SFAjvM007632@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090828/5d2d8fa6/attachment.html -------------- next part -------------- Modified: DART/trunk/observations/AIRS/work/path_names_advance_time =================================================================== --- DART/trunk/observations/AIRS/work/path_names_advance_time 2009-08-27 23:19:20 UTC (rev 4020) +++ DART/trunk/observations/AIRS/work/path_names_advance_time 2009-08-28 15:10:45 UTC (rev 4021) @@ -1,6 +1,6 @@ time_manager/advance_time.f90 time_manager/time_manager_mod.f90 common/types_mod.f90 -utilities/utilities_lite_mod.f90 +utilities/utilities_mod.f90 utilities/parse_args_mod.f90 mpi_utilities/null_mpi_utilities_mod.f90 From nancy at ucar.edu Fri Aug 28 09:49:03 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Fri, 28 Aug 2009 09:49:03 -0600 (MDT) Subject: [Dart-dev] [4022] DART/trunk/utilities/utilities_mod.f90: Make it so the nml file is really not opened or written to at all Message-ID: <200908281549.n7SFn3mH021122@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090828/501f366c/attachment.html -------------- next part -------------- Modified: DART/trunk/utilities/utilities_mod.f90 =================================================================== --- DART/trunk/utilities/utilities_mod.f90 2009-08-28 15:10:45 UTC (rev 4021) +++ DART/trunk/utilities/utilities_mod.f90 2009-08-28 15:49:03 UTC (rev 4022) @@ -289,30 +289,32 @@ ! If nmlfilename != logfilename, open it. otherwise set nmlfileunit ! to be same as logunit. - if (trim(adjustl(nmlfilename)) /= trim(adjustl(lname))) then - if (do_output_flag) & - write(*,*)'Trying to open namelist log ', trim(adjustl(nmlfilename)) - - nmlfileunit = nextunit() - if (nmlfileunit < 0) & - call error_handler(E_ERR,'initialize_utilities', & - 'Cannot get unit for nm log file', source, revision, revdate) - - open(nmlfileunit, file=trim(adjustl(nmlfilename)), form='formatted', & - position='append', iostat = io ) - if ( io /= 0 ) then - call error_handler(E_ERR,'initialize_utilities', & - 'Cannot open nm log file', source, revision, revdate) + if (do_nml_file()) then + if (trim(adjustl(nmlfilename)) /= trim(adjustl(lname))) then + if (do_output_flag) & + write(*,*)'Trying to open namelist log ', trim(adjustl(nmlfilename)) + + nmlfileunit = nextunit() + if (nmlfileunit < 0) & + call error_handler(E_ERR,'initialize_utilities', & + 'Cannot get unit for nm log file', source, revision, revdate) + + open(nmlfileunit, file=trim(adjustl(nmlfilename)), form='formatted', & + position='append', iostat = io ) + if ( io /= 0 ) then + call error_handler(E_ERR,'initialize_utilities', & + 'Cannot open nm log file', source, revision, revdate) + endif + + else + nmlfileunit = logfileunit endif - - else - nmlfileunit = logfileunit endif ! Echo the namelist values for this module using normal mechanism ! including a separator line for this run. if (do_output_flag) then - if (nmlfileunit /= logfileunit) then + if (do_nml_file() .and. (nmlfileunit /= logfileunit)) then if ( present(progname) ) then write(nmlfileunit, *) '!Starting Program '//trim(progname) else @@ -374,7 +376,7 @@ ! integer :: logfileunit -- private module variable if (do_output_flag) then - if (nmlfileunit /= logfileunit) then + if (do_nml_file() .and. (nmlfileunit /= logfileunit)) then write(nmlfileunit, *) '!Ending Program ' endif endif From nancy at ucar.edu Fri Aug 28 16:44:56 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Fri, 28 Aug 2009 16:44:56 -0600 (MDT) Subject: [Dart-dev] [4023] DART/trunk/DART_LAB/matlab/advance_oned.m: Added a model bias capability. Message-ID: <200908282244.n7SMiug3008668@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090828/5e0dbd22/attachment.html -------------- next part -------------- Modified: DART/trunk/DART_LAB/matlab/advance_oned.m =================================================================== --- DART/trunk/DART_LAB/matlab/advance_oned.m 2009-08-28 15:49:03 UTC (rev 4022) +++ DART/trunk/DART_LAB/matlab/advance_oned.m 2009-08-28 22:44:56 UTC (rev 4023) @@ -1,4 +1,4 @@ -function x_new = advance_oned(x, alpha) +function x_new = advance_oned(x, alpha, model_bias) % Data Assimilation Research Testbed -- DART % Copyright 2004-2009, Data Assimilation Research Section @@ -11,15 +11,16 @@ % $Revision$ % $Date$ -x_new = x + comp_dt(x, alpha); +x_new = x + comp_dt(x, alpha, model_bias); end %--------------------------------------------------- % Internal function comp_dt -function dx = comp_dt(x, alpha) +function dx = comp_dt(x, alpha, model_bias) % Compute the time tendency; alpha controls nonlinearity -dx = x + alpha .* x .* abs(x); +% model_bias controls a shift in the model dynamics +dx = (x + model_bias) + alpha .* x .* abs(x); end From nancy at ucar.edu Fri Aug 28 16:46:16 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Fri, 28 Aug 2009 16:46:16 -0600 (MDT) Subject: [Dart-dev] [4024] DART/trunk/DART_LAB/matlab: Enhanced capabilities and gui clean-up. Message-ID: <200908282246.n7SMkGNr009941@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090828/1283fa98/attachment-0001.html -------------- next part -------------- Modified: DART/trunk/DART_LAB/matlab/gaussian_product.fig =================================================================== (Binary files differ) Modified: DART/trunk/DART_LAB/matlab/oned_ensemble.fig =================================================================== (Binary files differ) Modified: DART/trunk/DART_LAB/matlab/oned_ensemble.m =================================================================== --- DART/trunk/DART_LAB/matlab/oned_ensemble.m 2009-08-28 22:44:56 UTC (rev 4023) +++ DART/trunk/DART_LAB/matlab/oned_ensemble.m 2009-08-28 22:46:16 UTC (rev 4024) @@ -29,7 +29,7 @@ % $Revision$ % $Date$ -% Last Modified by GUIDE v2.5 25-Mar-2009 14:34:04 +% Last Modified by GUIDE v2.5 28-Aug-2009 16:29:57 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -65,34 +65,43 @@ handles.output = hObject; % Insert the ensemble structure into this -handles.ens_size = 0; -handles.ens_members = 0; -handles.h_obs_plot = 0; -handles.h_update_ens = 0; -handles.h_ens_member = 0; -handles.h_obs_ast = 0; +handles.ens_size = 0; +handles.ens_members = 0; +handles.h_obs_plot = 0; +handles.h_update_ens = 0; +handles.h_ens_member = 0; +handles.h_obs_ast = 0; +handles.h_update_lines = 0; +handles.observation = 0; +handles.obs_error_sd = 0; +handles.inflation = 1.5; +handles.plot_inflation = false; +handles.h_inf_ens_member = 0; +handles.h_inf_up_ens = 0; +handles.h_inf_lines = 0; +handles.h_inf_axis = 0; % Update handles structure guidata(hObject, handles); +% Get the initial observation, obs_error_sd and inflation from the gui +handles.observation = str2double(get(handles.edit_observation, 'String')); +handles.obs_error_sd = str2double(get(handles.edit_obs_error_sd, 'String')); +handles.inflation = str2double(get(handles.edit_inflation, 'String')); + % Go ahead and plot the initial observational error distribution -h_observation = get(handles.edit1); -h_obs_error_sd = get(handles.edit2); -observation = str2double(h_observation.String); -obs_error_sd = str2double(h_obs_error_sd.String); -handles.h_obs_plot = plot_gaussian(observation, obs_error_sd, 1); +handles.h_obs_plot = plot_gaussian(handles.observation, handles.obs_error_sd, 1); set(handles.h_obs_plot, 'Color', 'r', 'Linestyle', '--', 'Linewidth', 2); hold on % Plot an asterisk -handles.h_obs_ast = plot(observation, 0, 'r*', 'MarkerSize', 16); +handles.h_obs_ast = plot(handles.observation, 0, 'r*', 'MarkerSize', 16); % Set a basic plotting domain range that includes mean +/- 3 obs SDs -lower = observation - 3*obs_error_sd; -upper = observation + 3*obs_error_sd; -axis([lower upper -0.2 1]); +lower = handles.observation - 3*handles.obs_error_sd; +upper = handles.observation + 3*handles.obs_error_sd; +axis([lower upper -0.4 1]); - set(gca, 'YTick', [0 0.2 0.4 0.6 0.8]); set(gca, 'YTickLabel', [0 0.2 0.4 0.6 0.8]); @@ -102,7 +111,6 @@ % Update handles structure guidata(hObject, handles); - % UIWAIT makes oned_ensemble wait for user response (see UIRESUME) % uiwait(handles.figure1); @@ -124,49 +132,51 @@ %---------------------------------------------------------------------- -% --- Executes on button press in pushbutton1. -function pushbutton1_Callback(hObject, eventdata, handles) -% hObject handle to pushbutton1 (see GCBO) +% --- Executes on button press in pushbutton_create_new. +function pushbutton_create_new_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton_create_new (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Disable the update ensemble button and all other active buttons -set(handles.pushbutton1, 'Enable', 'Off'); -set(handles.pushbutton2, 'Enable', 'Off'); -set(handles.edit1, 'Enable', 'Off'); -set(handles.edit2, 'Enable', 'Off'); +set(handles.pushbutton_update_ens, 'Enable', 'Off'); +set(handles.edit_observation, 'Enable', 'Off'); +set(handles.edit_obs_error_sd, 'Enable', 'Off'); +set(handles.edit_inflation, 'Enable', 'Off'); % Clear out any old ensemble members if they exist -for i = 1:handles.ens_size - set(handles.h_ens_member(i), 'Visible', 'off'); -end +set(handles.h_ens_member, 'Visible', 'off'); +set(handles.h_inf_ens_member, 'Visible', 'off'); -% Remove mean and sd of old ensemble -set(handles.text2, 'String', 'Prior Mean = '); -set(handles.text3, 'String', 'Prior SD = '); +set(handles.h_update_lines, 'Visible', 'off'); +set(handles.h_inf_lines, 'Visible', 'off'); +set(handles.h_inf_axis, 'Visible', 'off'); +% Turn off any old update points +set(handles.h_update_ens, 'Visible', 'off'); +set(handles.h_inf_up_ens, 'Visible', 'off'); +set(handles.h_inf_ens_member, 'Visible', 'off'); + +clear_labels(handles); + hold on + % Set a basic plotting domain range that includes mean +/- 3 obs SDs -h_observation = get(handles.edit1); -h_obs_error_sd = get(handles.edit2); -observation = str2double(h_observation.String); -obs_error_sd = str2double(h_obs_error_sd.String); -lower = observation - 3*obs_error_sd; -upper = observation + 3*obs_error_sd; -axis([lower upper -0.2 1]); +lower = min(handles.observation - 3*handles.obs_error_sd, min(handles.ens_members)); +upper = max(handles.observation + 3*handles.obs_error_sd, max(handles.ens_members)); +axis([lower upper -0.4 1]); set(gca, 'YTick', [0 0.2 0.4 0.6 0.8]); set(gca, 'YTickLabel', [0 0.2 0.4 0.6 0.8]); - % Messages should start 1/10 of the way across the screen x_message = lower + 0.1 * (upper - lower); -h_click = text(x_message, 0.7, 'Click on x-axis to create member', 'FontSize', 16); +h_click = text(x_message, 0.4, 'Click on x-axis to create member', 'FontSize', 16); % Need to guarantee at least 2 ensemble members ens_size = 0; -h_err_text = text(x_message, 0.9, 'Click inside graphics box to select member', ... +h_err_text = text(x_message, 0.5, 'Click inside graphics box to select member', ... 'Color', 'r', 'FontSize', 16, 'Visible', 'off'); while ens_size < 2 @@ -189,14 +199,12 @@ prior_sd = std(x); set(handles.text2, 'String', ['Prior Mean = ', num2str(prior_mean)]); set(handles.text3, 'String', ['Prior SD = ', num2str(prior_sd)]); - end end +h_finish = text(x_message, 0.3, 'Click outside of plot to finish', 'Fontsize', 16); -h_finish = text(x_message, 0.5, 'Click outside of plot to finish', 'Fontsize', 16); - -while ens_size < 1000 +while ens_size < 100 [xt, zt] = ginput(1); % Terminate by clicking outside of graph range if(xt > upper | xt < lower) @@ -213,9 +221,7 @@ prior_sd = std(x); set(handles.text2, 'String', ['Prior Mean = ', num2str(prior_mean)]); set(handles.text3, 'String', ['Prior SD = ', num2str(prior_sd)]); - end - end % Ensemble created, comupte mean and sd, clean up and return @@ -226,73 +232,82 @@ % Update handles structure guidata(hObject, handles); - % Turn off the data entry messages set(h_click, 'Visible', 'off'); set(h_finish, 'Visible', 'off'); % Enable the update ensemble button -set(handles.pushbutton1, 'Enable', 'On'); -set(handles.pushbutton2, 'Enable', 'On'); -set(handles.edit1, 'Enable', 'On'); -set(handles.edit2, 'Enable', 'On'); +set(handles.pushbutton_update_ens, 'Enable', 'On'); +set(handles.edit_observation, 'Enable', 'On'); +set(handles.edit_obs_error_sd, 'Enable', 'On'); +set(handles.edit_inflation, 'Enable', 'On'); %---------------------------------------------------------------------- -function edit1_Callback(hObject, eventdata, handles) -% hObject handle to edit1 (see GCBO) +function edit_observation_Callback(hObject, eventdata, handles) +% hObject handle to edit_observation (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -% Hints: get(hObject,'String') returns contents of edit1 as text -% str2double(get(hObject,'String')) returns contents of edit1 as a double +% Hints: get(hObject,'String') returns contents of edit_observation as text +% str2double(get(hObject,'String')) returns contents of edit_observation as a double +% Turn off any old updated points +set(handles.h_update_ens, 'Visible', 'off'); +set(handles.h_inf_up_ens, 'Visible', 'off'); +set(handles.h_inf_ens_member, 'Visible', 'off'); + +% Remove mean and sd of old posterior +clear_labels(handles); + +% And the lines in between +set(handles.h_update_lines, 'Visible', 'off'); +set(handles.h_inf_lines, 'Visible', 'off'); +set(handles.h_inf_axis, 'Visible', 'off'); + % Enable things that an error might have turned off -set(handles.edit2, 'Enable', 'on') -set(handles.pushbutton1, 'Enable', 'on') +set(handles.edit_obs_error_sd, 'Enable', 'on') +set(handles.edit_inflation, 'Enable', 'on') +set(handles.pushbutton_create_new, 'Enable', 'on') % Only enable the update ensemble pushbutton if an ensemble has been created if(handles.ens_size > 0) - set(handles.pushbutton2, 'Enable', 'on'); + set(handles.pushbutton_update_ens, 'Enable', 'on'); end % Get the value of the observation if(isfinite(str2double(get(hObject, 'String')))) observation = str2double(get(hObject, 'String')); else - set(handles.edit1, 'String', '???'); + set(handles.edit_observation, 'String', '???'); % Disable other input to guarantee only one error at a time! - set(handles.edit2, 'Enable', 'off') - set(handles.pushbutton1, 'Enable', 'off') - set(handles.pushbutton2, 'Enable', 'off') + set(handles.edit_obs_error_sd, 'Enable', 'off') + set(handles.edit_inflation, 'Enable', 'off') + set(handles.pushbutton_create_new, 'Enable', 'off') + set(handles.pushbutton_update_ens, 'Enable', 'off') return end -% Get the value of the observation error sd -h_obs_error_sd = get(handles.edit2); -obs_error_sd = str2double(h_obs_error_sd.String); +% Update the global storage +handles.observation = observation; % Plot the updated distribution set(handles.h_obs_plot, 'Visible', 'Off'); -handles.h_obs_plot = plot_gaussian(observation, obs_error_sd, 1); +handles.h_obs_plot = plot_gaussian(handles.observation, handles.obs_error_sd, 1); set(handles.h_obs_plot, 'Color', 'r', 'Linestyle', '--', 'Linewidth', 2); % Move the observation asterisk set(handles.h_obs_ast, 'Visible', 'Off'); -handles.h_obs_ast = plot(observation, 0, 'r*', 'MarkerSize', 16); +handles.h_obs_ast = plot(handles.observation, 0, 'r*', 'MarkerSize', 16); % Set a basic plotting domain range that includes mean +/- 3 obs SDs -h_observation = get(handles.edit1); -h_obs_error_sd = get(handles.edit2); -observation = str2double(h_observation.String); -obs_error_sd = str2double(h_obs_error_sd.String); -lower = observation - 3*obs_error_sd; -upper = observation + 3*obs_error_sd; -axis([lower upper -0.2 1]); +lower = min(handles.observation - 3*handles.obs_error_sd, min(handles.ens_members)); +upper = max(handles.observation + 3*handles.obs_error_sd, max(handles.ens_members)); +axis([lower upper -0.4 1]); set(gca, 'YTick', [0 0.2 0.4 0.6 0.8]); set(gca, 'YTickLabel', [0 0.2 0.4 0.6 0.8]); @@ -308,8 +323,8 @@ % --- Executes during object creation, after setting all properties. -function edit1_CreateFcn(hObject, eventdata, handles) -% hObject handle to edit1 (see GCBO) +function edit_observation_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_observation (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -323,21 +338,35 @@ %---------------------------------------------------------------------- -function edit2_Callback(hObject, eventdata, handles) -% hObject handle to edit2 (see GCBO) +function edit_obs_error_sd_Callback(hObject, eventdata, handles) +% hObject handle to edit_obs_error_sd (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -% Hints: get(hObject,'String') returns contents of edit2 as text -% str2double(get(hObject,'String')) returns contents of edit2 as a double +% Hints: get(hObject,'String') returns contents of edit_obs_error_sd as text +% str2double(get(hObject,'String')) returns contents of edit_obs_error_sd as a double +% Turn off any old updated points +set(handles.h_update_ens, 'Visible', 'off'); +set(handles.h_inf_up_ens, 'Visible', 'off'); +set(handles.h_inf_ens_member, 'Visible', 'off'); + +% Remove mean and sd of old posterior +clear_labels(handles); + +% And the lines in between +set(handles.h_update_lines, 'Visible', 'off'); +set(handles.h_inf_lines, 'Visible', 'off'); +set(handles.h_inf_axis, 'Visible', 'off'); + % Enable things that an error might have turned off -set(handles.edit1, 'Enable', 'on') -set(handles.pushbutton1, 'Enable', 'on') +set(handles.edit_observation, 'Enable', 'on') +set(handles.edit_inflation, 'Enable', 'on') +set(handles.pushbutton_create_new, 'Enable', 'on') % Only enable the update ensemble pushbutton if an ensemble has been created if(handles.ens_size > 0) - set(handles.pushbutton2, 'Enable', 'on'); + set(handles.pushbutton_update_ens, 'Enable', 'on'); end % Get the value of the observation @@ -345,32 +374,28 @@ str2double(get(hObject, 'String')) > 0) obs_error_sd = str2double(get(hObject, 'String')); else - set(handles.edit2, 'String', '???'); + set(handles.edit_obs_error_sd, 'String', '???'); % Disable other input to guarantee only one error at a time! - set(handles.edit1, 'Enable', 'off') - set(handles.pushbutton1, 'Enable', 'off') - set(handles.pushbutton2, 'Enable', 'off') + set(handles.edit_observation, 'Enable', 'off') + set(handles.edit_inflation, 'Enable', 'off') + set(handles.pushbutton_create_new, 'Enable', 'off') + set(handles.pushbutton_update_ens, 'Enable', 'off') return end -% Get the value of the observation -h_observation = get(handles.edit1); -observation = str2double(h_observation.String); +% Update the value in global storage +handles.obs_error_sd = obs_error_sd; % Plot the updated distribution set(handles.h_obs_plot, 'Visible', 'off'); -handles.h_obs_plot = plot_gaussian(observation, obs_error_sd, 1); +handles.h_obs_plot = plot_gaussian(handles.observation, handles.obs_error_sd, 1); set(handles.h_obs_plot, 'Color', 'r', 'Linestyle', '--', 'Linewidth', 2); % Set a basic plotting domain range that includes mean +/- 3 obs SDs -h_observation = get(handles.edit1); -h_obs_error_sd = get(handles.edit2); -observation = str2double(h_observation.String); -obs_error_sd = str2double(h_obs_error_sd.String); -lower = observation - 3*obs_error_sd; -upper = observation + 3*obs_error_sd; -axis([lower upper -0.2 1]); +lower = min(handles.observation - 3*handles.obs_error_sd, min(handles.ens_members)); +upper = max(handles.observation + 3*handles.obs_error_sd, max(handles.ens_members)); +axis([lower upper -0.4 1]); set(handles.h_obs_plot, 'Color', 'r', 'Linestyle', '--', 'Linewidth', 2); @@ -388,8 +413,8 @@ % --- Executes during object creation, after setting all properties. -function edit2_CreateFcn(hObject, eventdata, handles) -% hObject handle to edit2 (see GCBO) +function edit_obs_error_sd_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_obs_error_sd (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -403,22 +428,22 @@ %---------------------------------------------------------------------- -% --- Executes on selection change in popupmenu1. -function popupmenu1_Callback(hObject, eventdata, handles) -% hObject handle to popupmenu1 (see GCBO) +% --- Executes on selection change in popupmenu_filter_kind. +function popupmenu_filter_kind_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu_filter_kind (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -% Hints: contents = get(hObject,'String') returns popupmenu1 contents as cell array -% contents{get(hObject,'Value')} returns selected item from popupmenu1 +% Hints: contents = get(hObject,'String') returns popupmenu_filter_kind contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu_filter_kind %---------------------------------------------------------------------- % --- Executes during object creation, after setting all properties. -function popupmenu1_CreateFcn(hObject, eventdata, handles) -% hObject handle to popupmenu1 (see GCBO) +function popupmenu_filter_kind_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu_filter_kind (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -432,37 +457,42 @@ %---------------------------------------------------------------------- -% --- Executes on button press in pushbutton2. -function pushbutton2_Callback(hObject, eventdata, handles) -% hObject handle to pushbutton2 (see GCBO) +% --- Executes on button press in pushbutton_update_ens. +function pushbutton_update_ens_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton_update_ens (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Turn off any old points set(handles.h_update_ens, 'Visible', 'off'); +set(handles.h_inf_up_ens, 'Visible', 'off'); +set(handles.h_inf_ens_member, 'Visible', 'off'); +% Remove mean and sd of old posterior +clear_labels(handles); + +% And the lines in between +set(handles.h_update_lines, 'Visible', 'off'); +set(handles.h_inf_lines, 'Visible', 'off'); +set(handles.h_inf_axis, 'Visible', 'off'); + ensemble = handles.ens_members; -h_observation = get(handles.edit1); -h_obs_error_sd = get(handles.edit2); -observation = str2double(h_observation.String); -obs_error_sd = str2double(h_obs_error_sd.String); - % Figure out which filter option is currently selected -h_filter_kind = get(handles.popupmenu1); +h_filter_kind = get(handles.popupmenu_filter_kind); filter_type = char(h_filter_kind.String(h_filter_kind.Value)); switch filter_type case 'EAKF' [obs_increments, err] = ... - obs_increment_eakf(ensemble, observation, obs_error_sd^2); + obs_increment_eakf(ensemble, handles.observation, handles.obs_error_sd^2); case 'EnKF' [obs_increments, err] = ... - obs_increment_enkf(ensemble, observation, obs_error_sd^2); + obs_increment_enkf(ensemble, handles.observation, handles.obs_error_sd^2); case 'RHF' [obs_increments, err] = ... - obs_increment_rhf(ensemble, observation, obs_error_sd^2); + obs_increment_rhf(ensemble, handles.observation, handles.obs_error_sd^2); end % Add on increments to get new ensemble @@ -470,4 +500,209 @@ y(1:size(ensemble)) = -0.1; handles.h_update_ens = plot(new_ensemble, y, '*', 'MarkerSize', 16, 'Color', 'Blue'); + +% Plot lines connecting the prior and posterior ensemble members +for i = 1:size(ensemble, 2) + x_line = [handles.ens_members(i), new_ensemble(i)]; + y_line = [0, -0.1]; + handles.h_update_lines(i) = plot(x_line, y_line, 'k'); +end + +% Add in a label of the updated mean and sd +new_mean = mean(new_ensemble); +new_sd = std(new_ensemble); + +% Update mean and sd of old posterior +set(handles.text8, 'String', ['Prior Mean = ', num2str(new_mean)]); +set(handles.text8, 'Visible', 'on'); +set(handles.text7, 'String', ['Prior SD = ', num2str(new_sd)]); +set(handles.text7, 'Visible', 'on'); + +% If the checkbox isn't set, return now +if(not(get(handles.checkbox_inflation, 'Value'))) + guidata(hObject, handles) + return +end + +% Plot the inflated prior ensemble +y = -0.2; +prior_mean = mean(handles.ens_members(1:handles.ens_size)); + +for i = 1: handles.ens_size + inf_ens(i) = (handles.ens_members(i) - prior_mean) * sqrt(handles.inflation) + ... + prior_mean; + handles.h_inf_ens_member(i) = plot(inf_ens(i), y, '*', 'MarkerSize', 16, 'Color', [0 0.73 0]); +end + +% Update mean and sd of old posterior +inf_prior_sd = std(inf_ens(1:handles.ens_size)); +set(handles.text9, 'String', ['Inflated = ', num2str(prior_mean)]); +set(handles.text9, 'Visible', 'on'); +set(handles.text10, 'String', ['Inflated = ', num2str(inf_prior_sd)]); +set(handles.text10, 'Visible', 'on'); + + +% Get the update for the inflated ensemble +switch filter_type + case 'EAKF' + [obs_increments, err] = ... + obs_increment_eakf(inf_ens, handles.observation, handles.obs_error_sd^2); + case 'EnKF' + [obs_increments, err] = ... + obs_increment_enkf(inf_ens, handles.observation, handles.obs_error_sd^2); + case 'RHF' + [obs_increments, err] = ... + obs_increment_rhf(inf_ens, handles.observation, handles.obs_error_sd^2); +end + +% Add on increments to get new ensemble +new_ensemble = inf_ens + obs_increments; + +y(1:size(ensemble)) = -0.3; +handles.h_inf_up_ens = plot(new_ensemble, y, '*', 'MarkerSize', 16, 'Color', 'Blue'); + +% Plot lines connecting the prior and posterior ensemble members +for i = 1:size(ensemble, 2) + x_line = [inf_ens(i), new_ensemble(i)]; + y_line = [-0.2, -0.3]; + handles.h_inf_lines(i) = plot(x_line, y_line, 'k'); +end + +% Set a basic plotting domain range that includes mean +/- 3 obs SDs +% Plus all inflated members +lower = min(handles.observation - 3*handles.obs_error_sd, min(inf_ens)); +upper = max(handles.observation + 3*handles.obs_error_sd, max(inf_ens)); +axis([lower upper -0.4 1]); + +% Plot the axes for the two priors +plot([lower upper], [0 0], 'k', 'Linewidth', 2); +handles.h_inf_axis = plot([lower upper], [-0.2 -0.2], 'k', 'Linewidth', 2); + +% Update mean and sd of old posterior +update_inf_mean = mean(new_ensemble(1:handles.ens_size)); +update_inf_sd = std(new_ensemble(1:handles.ens_size)); +set(handles.text12, 'String', ['Inflated = ', num2str(update_inf_mean)]); +set(handles.text12, 'Visible', 'on'); +set(handles.text11, 'String', ['Inflated = ', num2str(update_inf_sd)]); +set(handles.text11, 'Visible', 'on'); + guidata(hObject, handles) + + + + + +% --- Executes on button press in checkbox_inflation. +function checkbox_inflation_Callback(hObject, eventdata, handles) +% hObject handle to checkbox_inflation (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of checkbox_inflation + + + + +function clear_labels(handles) + +% Turns off all labels except for the prior mean and SD +set(handles.text9, 'Visible', 'off'); +set(handles.text10, 'Visible', 'off'); +set(handles.text8, 'Visible', 'off'); +set(handles.text7, 'Visible', 'off'); +set(handles.text12, 'Visible', 'off'); +set(handles.text11, 'Visible', 'off'); + + + + + +function edit_inflation_Callback(hObject, eventdata, handles) +% hObject handle to edit_inflation (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit_inflation as text +% str2double(get(hObject,'String')) returns contents of edit_inflation as a double + +% Turn off any old updated points +set(handles.h_update_ens, 'Visible', 'off'); +set(handles.h_inf_up_ens, 'Visible', 'off'); +set(handles.h_inf_ens_member, 'Visible', 'off'); + +% Remove mean and sd of old posterior +clear_labels(handles); + +% And the lines in between +set(handles.h_update_lines, 'Visible', 'off'); +set(handles.h_inf_lines, 'Visible', 'off'); +set(handles.h_inf_axis, 'Visible', 'off'); + +% Enable things that an error might have turned off +set(handles.edit_observation, 'Enable', 'on') +set(handles.edit_obs_error_sd, 'Enable', 'on') +set(handles.pushbutton_create_new, 'Enable', 'on') + +% Only enable the update ensemble pushbutton if an ensemble has been created +if(handles.ens_size > 0) + set(handles.pushbutton_update_ens, 'Enable', 'on'); +end + +% Get the value of the observation +if(isfinite(str2double(get(hObject, 'String'))) && ... + str2double(get(hObject, 'String')) > 0) + inflation = str2double(get(hObject, 'String')); +else + set(handles.edit_inflation, 'String', '???'); + + % Disable other input to guarantee only one error at a time! + set(handles.edit_observation, 'Enable', 'off') + set(handles.edit_obs_error_sd, 'Enable', 'off') + set(handles.pushbutton_create_new, 'Enable', 'off') + set(handles.pushbutton_update_ens, 'Enable', 'off') + return +end + +% Update the value in global storage +handles.inflation = inflation; + +% Plot the updated distribution +set(handles.h_obs_plot, 'Visible', 'off'); +handles.h_obs_plot = plot_gaussian(handles.observation, handles.obs_error_sd, 1); +set(handles.h_obs_plot, 'Color', 'r', 'Linestyle', '--', 'Linewidth', 2); + +% Set a basic plotting domain range that includes mean +/- 3 obs SDs +lower = min(handles.observation - 3*handles.obs_error_sd, min(handles.ens_members)); +upper = max(handles.observation + 3*handles.obs_error_sd, max(handles.ens_members)); +axis([lower upper -0.4 1]); + +set(handles.h_obs_plot, 'Color', 'r', 'Linestyle', '--', 'Linewidth', 2); + +set(gca, 'YTick', [0 0.2 0.4 0.6 0.8]); +set(gca, 'YTickLabel', [0 0.2 0.4 0.6 0.8]); + +hold on +plot([lower upper], [0 0], 'k', 'Linewidth', 2); + +% Update handles structure +guidata(hObject, handles); + + + + + + + +% --- Executes during object creation, after setting all properties. +function edit_inflation_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_inflation (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + Modified: DART/trunk/DART_LAB/matlab/oned_model.fig =================================================================== (Binary files differ) Modified: DART/trunk/DART_LAB/matlab/oned_model.m =================================================================== --- DART/trunk/DART_LAB/matlab/oned_model.m 2009-08-28 22:44:56 UTC (rev 4023) +++ DART/trunk/DART_LAB/matlab/oned_model.m 2009-08-28 22:46:16 UTC (rev 4024) @@ -5,7 +5,7 @@ % % ONED_MODEL demonstrates the simplest possible case of ensemble data % assimilation. It is possible to explore assimilation algorithms, -% ensemble sizes, observation biases, etc. on-the-fly. The posterior +% ensemble sizes, model biases, etc. on-the-fly. The posterior % of the state is indicated by blue asterisks, the states evolve along % a tajectory indicated by the green lines to wind up at a prior state % for the assimilation - indicated by the green asterisks. After the @@ -44,7 +44,7 @@ % $Revision$ % $Date$ -% Last Modified by GUIDE v2.5 06-May-2009 08:31:46 +% Last Modified by GUIDE v2.5 27-Aug-2009 08:54:05 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -91,7 +91,8 @@ handles.error = 0; handles.spread = 0; handles.kurtosis = 0; -handles.obs_bias = 0; +handles.model_bias = 0; +handles.inflation = 1.0; % An array to keep track of rank histograms handles.prior_rank(1 : handles.ens_size + 1) = 0; @@ -202,16 +203,21 @@ % Hints: get(hObject,'String') returns contents of edit1 as text % str2double(get(hObject,'String')) returns contents of edit1 as a double -% Get the value of the obs_bias -if(isfinite(str2double(get(hObject, 'String')))) - handles.obs_bias = str2double(get(hObject, 'String')); -else +% Get the value of the model_bias +handles.model_bias = str2double(get(hObject, 'String')); +if(not(isfinite(handles.model_bias))) + % Indicate input error in text box set(handles.edit1, 'String', '???'); - % Disable other input to guarantee only one error at a time! + % After this, only this edit box will work + turn_off_controls(handles); + set(handles.edit1, 'Enable', 'On'); + return end +% Turn on all controls if successful +turn_on_controls(handles) % Update handles structure guidata(hObject, handles); @@ -314,15 +320,20 @@ % str2double(get(hObject,'String')) returns contents of edit5 as a double % Get the value of the model nonlinearity parameter -if(isfinite(str2double(get(hObject, 'String')))) - handles.alpha= str2double(get(hObject, 'String')); -else +handles.alpha= str2double(get(hObject, 'String')); +if(not(isfinite(handles.alpha)) | handles.alpha < 0) + % Indicate input error in text box set(handles.edit5, 'String', '???'); - % Disable other input to guarantee only one error at a time! + % After this, only this edit box will work + turn_off_controls(handles); + set(handles.edit5, 'Enable', 'On'); + return end +% Enable all controls +turn_on_controls(handles); % Update handles structure guidata(hObject, handles); @@ -364,6 +375,23 @@ return end +% Get the value of the ensemble size +new_ens_size = str2double(get(hObject, 'String')); +if(not(isfinite(new_ens_size)) | new_ens_size < 2) + % Indicate input error in text box + set(handles.edit6, 'String', '???'); + + % After this, only this edit box will work + turn_off_controls(handles); + set(handles.edit6, 'Enable', 'On'); + + return +end + +% Legal value for ensemble size; enable all controls +turn_on_controls(handles); + +% Reset the histograms handles = reset_histograms(new_ens_size, hObject, handles); % Generate a new ensemble by truncating old ensemble OR adding new @@ -514,14 +542,9 @@ % Turn off all the other controls to avoid a mess -set(handles.pushbutton1, 'Enable', 'Off'); -set(handles.reset_pushbutton, 'Enable', 'Off'); -set(handles.edit1, 'Enable', 'Off'); -set(handles.edit5, 'Enable', 'Off'); -set(handles.edit6, 'Enable', 'Off'); -set(handles.popupmenu1, 'Enable', 'Off'); +turn_off_controls(handles) +set(handles.pushbutton_run, 'Enable', 'On'); - if(strcmp(get(hObject, 'String'), 'Stop Free Run')) % Being told to stop; switch to not running status set(hObject, 'String', 'Start Free Run'); @@ -541,31 +564,19 @@ status_string = get(my_data.pushbutton_run, 'String'); if(strcmp(status_string, 'Start Free Run')) % Turn all the other controls back on - set(handles.pushbutton1, 'Enable', 'On'); - set(handles.reset_pushbutton, 'Enable', 'On'); - set(handles.edit1, 'Enable', 'On'); - set(handles.edit5, 'Enable', 'On'); - set(handles.edit6, 'Enable', 'On'); - set(handles.popupmenu1, 'Enable', 'On'); - + turn_on_controls(handles); return end % Do the next advance or assimilation step step_ahead(hObject, my_data) - pause(1) + pause(0.2) end end % Turn all the other controls back on -set(handles.pushbutton1, 'Enable', 'On'); -set(handles.reset_pushbutton, 'Enable', 'On'); -set(handles.edit1, 'Enable', 'On'); -set(handles.edit5, 'Enable', 'On'); -set(handles.edit6, 'Enable', 'On'); -set(handles.popupmenu1, 'Enable', 'On'); +turn_on_controls(handles); - %----------- Moves the model ahead or assimilates next observations ------ function step_ahead(hObject, handles) @@ -578,7 +589,14 @@ % Set to do an assimilation next time handles.ready_to_advance = false; % Advance the model - ens_new = advance_oned(handles.ens, handles.alpha); + ens_new = advance_oned(handles.ens, handles.alpha, handles.model_bias); + +% Inflate the model + ens_new_mean = mean(ens_new); + ens_new = (ens_new - ens_new_mean) * sqrt(handles.inflation) + ens_new_mean; + + + handles.time_step = handles.time_step + 1; h = plot(handles.time_step - 0.1, ens_new, '*', 'MarkerSize', 6); set(h, 'Color', [0 0.73 0]); @@ -710,7 +728,7 @@ handles.ready_to_advance = true; % Generate the observation as a draw Normal(0, 1) obs_error_sd = handles.obs_error_sd; - observation = randn(obs_error_sd) + handles.obs_bias; + observation = randn(obs_error_sd); % Plot the observation plot(handles.time_step, observation, 'r*', 'MarkerSize', 10); @@ -918,3 +936,77 @@ +function edit7_Callback(hObject, eventdata, handles) +% hObject handle to edit7 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit7 as text +% str2double(get(hObject,'String')) returns contents of edit7 as a double + +% Get the value of the model_bias +handles.inflation= str2double(get(hObject, 'String')); +if(not(isfinite(handles.inflation)) | handles.inflation < 1) + % Indicate input error in text box + set(handles.edit7, 'String', '???'); + + % After this, only this edit box will work + turn_off_controls(handles); + set(handles.edit7, 'Enable', 'On'); + + return +end + +% Turn on all the controls +turn_on_controls(handles); + +% Update handles structure +guidata(hObject, handles); + + + +% --- Executes during object creation, after setting all properties. +function edit7_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit7 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +%-----------Turns off all the controls---------- +function turn_off_controls(handles) + +% Turn off all the other controls to avoid a mess +set(handles.pushbutton1, 'Enable', 'Off'); +set(handles.pushbutton_run, 'Enable', 'Off'); +set(handles.reset_pushbutton, 'Enable', 'Off'); +set(handles.edit1, 'Enable', 'Off'); +set(handles.edit5, 'Enable', 'Off'); +set(handles.edit6, 'Enable', 'Off'); +set(handles.edit7, 'Enable', 'Off'); +set(handles.popupmenu1, 'Enable', 'Off'); + + + + +%-----------Turns on all the controls---------- +function turn_on_controls(handles) + +% Turn on all the other controls to avoid a mess +set(handles.pushbutton1, 'Enable', 'On'); +set(handles.pushbutton_run, 'Enable', 'On'); +set(handles.reset_pushbutton, 'Enable', 'On'); +set(handles.edit1, 'Enable', 'On'); +set(handles.edit5, 'Enable', 'On'); +set(handles.edit6, 'Enable', 'On'); +set(handles.edit7, 'Enable', 'On'); +set(handles.popupmenu1, 'Enable', 'On'); + + + Modified: DART/trunk/DART_LAB/matlab/run_lorenz_96.fig =================================================================== (Binary files differ) Modified: DART/trunk/DART_LAB/matlab/run_lorenz_96.m =================================================================== --- DART/trunk/DART_LAB/matlab/run_lorenz_96.m 2009-08-28 22:44:56 UTC (rev 4023) +++ DART/trunk/DART_LAB/matlab/run_lorenz_96.m 2009-08-28 22:46:16 UTC (rev 4024) @@ -30,7 +30,7 @@ % $Revision$ % $Date$ -% Last Modified by GUIDE v2.5 02-Jun-2009 15:44:28 +% Last Modified by GUIDE v2.5 27-Aug-2009 16:35:11 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -88,15 +88,15 @@ handles.h_truth = 0; % Generate set of ensemble perturbations -for n = 1:ens_size +for n = 1:handles.ens_size handles.post(1, 1:MODEL_SIZE, n) = handles.true_state(1, :); end -handles.post(1, 1:MODEL_SIZE, 1:ens_size) = ... - handles.post(1, 1:MODEL_SIZE, 1:ens_size) + ... - 0.001 * randn(1, MODEL_SIZE, ens_size); +handles.post(1, 1:MODEL_SIZE, 1:handles.ens_size) = ... + handles.post(1, 1:MODEL_SIZE, 1:handles.ens_size) + ... + 0.001 * randn(1, MODEL_SIZE, handles.ens_size); % For convenience make the first prior identical to the first posterior -handles.prior(1, 1:MODEL_SIZE, 1:ens_size) = handles.post; +handles.prior(1, 1:MODEL_SIZE, 1:handles.ens_size) = handles.post; % Update handles structure @@ -470,3 +470,58 @@ end + +function edit_ens_size_Callback(hObject, eventdata, handles) +% hObject handle to edit_ens_size (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit_ens_size as text +% str2double(get(hObject,'String')) returns contents of edit_ens_size as a double + +% Set the ensemble size global value to the update +handles.ens_size = str2double(get(hObject, 'String')); +if(not(isfinite(handles.ens_size)) | handles.ens_size < 2) + set(handles.edit_ens_size, 'String', '???'); + + % After this, only this edit box will work + %%%turn_off_controls(handles); + set(handles.edit_ens_size, 'Enable', 'On'); + + return +end + +% Enable all controls +%%%turn_on_controls(handles); + +% Need to reset the ensemble and the time +slkjdf + + + +% Update handles structure +guidata(hObject, handles); + + + + +% --- Executes during object creation, after setting all properties. +function edit_ens_size_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_ens_size (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes when uipanel2 is resized. +function uipanel2_ResizeFcn(hObject, eventdata, handles) +% hObject handle to uipanel2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + From nancy at ucar.edu Mon Aug 31 15:25:29 2009 From: nancy at ucar.edu (nancy at ucar.edu) Date: Mon, 31 Aug 2009 15:25:29 -0600 (MDT) Subject: [Dart-dev] [4025] DART/trunk/models/POP: A non-advancing 'perfect model' assimilation and 'filter' worked for a Message-ID: <200908312125.n7VLPTg1000897@subversion.ucar.edu> An HTML attachment was scrubbed... URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090831/27d0d990/attachment.html -------------- next part -------------- Modified: DART/trunk/models/POP/dart_pop_mod.f90 =================================================================== --- DART/trunk/models/POP/dart_pop_mod.f90 2009-08-28 22:46:16 UTC (rev 4024) +++ DART/trunk/models/POP/dart_pop_mod.f90 2009-08-31 21:25:29 UTC (rev 4025) @@ -66,6 +66,17 @@ stop_option, stop_count, date_separator, allow_leapyear, fit_freq !------------------------------------------------------------------ +! The POP I/O namelist variables +!------------------------------------------------------------------ + +character(len=100) :: log_filename, pointer_filename +logical :: lredirect_stdout, luse_pointer_files +integer :: num_iotasks + +namelist /io_nml/ num_iotasks, lredirect_stdout, log_filename, & + luse_pointer_files, pointer_filename + +!------------------------------------------------------------------ ! The POP restart manager namelist variables !------------------------------------------------------------------ @@ -168,25 +179,46 @@ call set_calendar_type('noleap') endif +! Read POP I/O information (for restart file ... grid dimensions) ! Read POP initial information (for input/restart filename) -! The tricky part here is that we should really check for -! the existence of the init_ts_file and take evasive action -! like checking for the existence of a pointer file. +call find_namelist_in_file('pop_in', 'io_nml', iunit) +read(iunit, nml = io_nml, iostat = io) +call check_namelist_read(iunit, io, 'io_nml') + call find_namelist_in_file('pop_in', 'init_ts_nml', iunit) read(iunit, nml = init_ts_nml, iostat = io) call check_namelist_read(iunit, io, 'init_ts_nml') -ic_filename = trim(init_ts_file)//'.'//trim(init_ts_file_fmt) +! Is it a pointer file or not ... +if ( luse_pointer_files ) then -! FIXME ... what about the pointer file ... + restart_filename = trim(pointer_filename)//'.restart' + + if ( .not. file_exist(restart_filename) ) then + msgstring = 'pop_in:pointer file '//trim(restart_filename)//' not found' + call error_handler(E_ERR,'initialize_module', & + msgstring, source, revision, revdate) + endif + + iunit = open_file(restart_filename,'formatted') + read(iunit,'(A)')ic_filename + + restart_filename = ' ' + write(*,*)'DEBUG ... pointer filename dereferenced to ',trim(ic_filename ) + +else + ic_filename = trim(init_ts_file)//'.'//trim(init_ts_file_fmt) +endif + +! Make sure we have a pop restart file (for grid dims) if ( .not. file_exist(ic_filename) ) then msgstring = 'pop_in:init_ts_file '//trim(ic_filename)//' not found' call error_handler(E_ERR,'initialize_module', & msgstring, source, revision, revdate) endif -! Read POP restart information (for model timestepping/grid dimensions) +! Read POP restart information (for model timestepping) call find_namelist_in_file('pop_in', 'restart_nml', iunit) read(iunit, nml = restart_nml, iostat = io) call check_namelist_read(iunit, io, 'restart_nml') @@ -196,7 +228,7 @@ read(iunit, nml = domain_nml, iostat = io) call check_namelist_read(iunit, io, 'domain_nml') -! Read POP grid information (for grid dims/filenames) +! Read POP grid information (for grid filenames) call find_namelist_in_file('pop_in', 'grid_nml', iunit) read(iunit, nml = grid_nml, iostat = io) call check_namelist_read(iunit, io, 'grid_nml') Modified: DART/trunk/models/POP/dart_to_pop.f90 =================================================================== --- DART/trunk/models/POP/dart_to_pop.f90 2009-08-28 22:46:16 UTC (rev 4024) +++ DART/trunk/models/POP/dart_to_pop.f90 2009-08-31 21:25:29 UTC (rev 4025) @@ -47,7 +47,7 @@ ! The namelist variables !------------------------------------------------------------------ -character (len = 128) :: dart_to_pop_input_file = 'assim_model_state_ic' +character (len = 128) :: dart_to_pop_input_file = 'filter_ics' character (len = 128) :: dart_to_pop_restart_file = 'my_pop_restart_file' logical :: advance_time_present = .TRUE. Added: DART/trunk/models/POP/shell_scripts/run_perfect_model_obs.batch =================================================================== --- DART/trunk/models/POP/shell_scripts/run_perfect_model_obs.batch (rev 0) +++ DART/trunk/models/POP/shell_scripts/run_perfect_model_obs.batch 2009-08-31 21:25:29 UTC (rev 4025) @@ -0,0 +1,223 @@ +#!/bin/csh +# +#BXXX -b 18:00 +#BSUB -J POP_OSSE +#BSUB -o POP_OSSE.%J.log +#BSUB -N -u ${USER}@ucar.edu +#BSUB -q economy +#BSUB -n 16 +#BSUB -R "span[ptile=2]" +#BSUB -W 2:00 +#BSUB -m "cr0128en cr0129en cr0130en cr0131en cr0132en cr0133en cr0134en cr0135en cr0136en cr0137en cr0138en cr0139en cr0140en cr0141en cr0202en cr0201en" +# +#----------------------------------------------------------------------------- +# Data Assimilation Research Testbed -- DART +# Copyright 2004-2009, Data Assimilation Research Section +# University Corporation for Atmospheric Research +# Licensed under the GPL -- www.gpl.org/licenses/gpl.html +# +# +# $URL: http://subversion.ucar.edu/DAReS/DART/trunk/models/POP/shell_scripts/job.simple.csh $ +# $Id: job.simple.csh 3575 2008-08-21 18:01:05Z thoar $ +# $Revision: 3575 $ +# $Date: 2008-08-21 12:01:05 -0600 (Thu, 21 Aug 2008) $ +#----------------------------------------------------------------------------- +# run_perfect_model_obs.batch ... Top level script to generate observations and a TRUE state. +# +# Unlike the more complex job.csh, this script only processes a single +# observation file. Still fairly complex; requires a raft of +# data files and most of them are in hardcoded locations. +# +# This script is designed to be run from the command line (as a single thread) +# and should only take a few seconds to a minute to complete, depending on +# the filesystem performance and data file size. +# +# The script moves the necessary files to the current directory - in DART +# nomenclature, this will be called CENTRALDIR. +# After everything is confirmed to have been assembled, it is possible +# to edit the data, data.cal, and input.nml files for the specifics of +# the experiment; as well as allow final configuration of a 'nodelist' file. +# +# Once the 'table is set', all that remains is to start/submit the +# 'runme_filter' script. That script will spawn 'filter' as a +# parallel job on the appropriate nodes; each of these tasks will +# call a separate model_advance.csh when necessary. +# +# The central directory is where the scripts reside and where script and +# program I/O are expected to happen. +#----------------------------------------------------------------------------- + +#---------------------------------------------------------------------- +# Turns out the scripts are a lot more flexible if you don't rely on +# the queuing-system-specific variables -- so I am converting them to +# 'generic' names and using the generics throughout the remainder. +#---------------------------------------------------------------------- + +if ($?LSB_HOSTS) then + + setenv ORIGINALDIR $LS_SUBCWD + setenv JOBNAME $LSB_OUTPUTFILE:ar + setenv JOBID $LSB_JOBID + setenv MYQUEUE $LSB_QUEUE + setenv MYHOST $LSB_SUB_HOST + +else + + #------------------------------------------------------------------- + # You can run this interactively to check syntax, file motion, etc. + #------------------------------------------------------------------- + + setenv ORIGINALDIR `pwd` + setenv JOBNAME POP + setenv JOBID $$ + setenv MYQUEUE Interactive + setenv MYHOST $host + +endif + +#---------------------------------------------------------------------- +# Just an echo of job attributes +#---------------------------------------------------------------------- + +echo +echo "${JOBNAME} ($JOBID) submitted from $ORIGINALDIR" +echo "${JOBNAME} ($JOBID) submitted from $MYHOST" +echo "${JOBNAME} ($JOBID) running in queue $MYQUEUE" +echo "${JOBNAME} ($JOBID) running on $host" +echo "${JOBNAME} ($JOBID) started at "`date` +echo + +#---------------------------------------------------------------------- +# Make a unique, (empty, clean) temporary directory. +#---------------------------------------------------------------------- + +setenv TMPDIR /ptmp/${user}/${JOBNAME}/job_${JOBID} + +mkdir -p ${TMPDIR} +cd ${TMPDIR} + +set CENTRALDIR = `pwd` +set myname = $0 # this is the name of this script + +# some systems don't like the -v option to any of the following + +set OSTYPE = `uname -s` +switch ( ${OSTYPE} ) + case IRIX64: + setenv REMOVE 'rm -rf' + setenv COPY 'cp -p' + setenv MOVE 'mv -f' + breaksw + case AIX: + setenv REMOVE 'rm -rf' + setenv COPY 'cp -p' + setenv MOVE 'mv -f' + breaksw + default: + setenv REMOVE 'rm -rvf' + setenv COPY 'cp -vp' + setenv MOVE 'mv -fv' + breaksw +endsw + +echo "${JOBNAME} ($JOBID) CENTRALDIR == $CENTRALDIR" + +#----------------------------------------------------------------------------- +# Set variables containing various directory names where we will GET things +#----------------------------------------------------------------------------- + +set DARTDIR = /fs/image/home/${user}/SVN/DART/models/POP +set POPDIR = /fs/image/home/${user}/SVN/DART/models/POP/input + +#----------------------------------------------------------------------------- +# Get the DART executables, scripts, and input files +#----------------------------------------------------------------------------- + +# executables +${COPY} ${DARTDIR}/work/perfect_model_obs . +${COPY} ${DARTDIR}/work/dart_to_pop . +${COPY} ${DARTDIR}/work/pop_to_dart . + +# shell scripts +${COPY} ${DARTDIR}/shell_scripts/advance_model.csh . + +# data files +${COPY} ${DARTDIR}/work/obs_seq.in . +${COPY} ${DARTDIR}/work/dart.ics perfect_ics +${COPY} ${DARTDIR}/work/input.nml . + +#----------------------------------------------------------------------------- +# Get the POP executable, control files, and data files. +# trying to use the CCSM naming conventions +#----------------------------------------------------------------------------- + +${COPY} ${POPDIR}/pop . +${COPY} ${POPDIR}/pop_in.part1 . +${COPY} ${POPDIR}/pop_in.part2 . +${COPY} ${POPDIR}/pop.r.nc . +echo "pop.r.nc" >! pop_pointer.restart + +${COPY} ${POPDIR}/gx3v5_tavg_contents . +${COPY} ${POPDIR}/gx3v5_movie_contents . +${COPY} ${POPDIR}/gx3v5_history_contents . +${COPY} ${POPDIR}/gx3v5_transport_contents . + +${COPY} ${POPDIR}/vert_grid.gx3v5 . +${COPY} ${POPDIR}/horiz_grid.gx3v5.r8ieee.le . +${COPY} ${POPDIR}/topography.gx3v5.r8ieee.le . + +#${COPY} ${POPDIR}/chl_mm_SeaWiFs97-01_20031205.ieeer8 . +#${COPY} ${POPDIR}/sfwf_20040517.ieeer8 . +#${COPY} ${POPDIR}/shf_20031208.ieeer8 . +#${COPY} ${POPDIR}/tidal_energy_gx3v5_20081021.ieeer8 . +#${COPY} ${POPDIR}/ts_PHC2_jan_20030806.ieeer8 . + +#----------------------------------------------------------------------------- +# Check that everything moved OK, and the table is set. +# Gives us a chance to edit the local input.nml, data.cal, etc. if needed. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Run perfect_model_obs ... harvest the observations to populate obs_seq.out +#----------------------------------------------------------------------------- + +cat pop_in.part1 pop_in.part2 >! pop_in + +./perfect_model_obs + +echo "${JOBNAME} ($JOBID) finished at "`date` + +#----------------------------------------------------------------------------- +# Move the output to storage after filter completes. +# At this point, all the restart,diagnostic files are in the CENTRALDIR +# and need to be moved to the 'experiment permanent' directory. +# We have had problems with some, but not all, files being moved +# correctly, so we are adding bulletproofing to check to ensure the filesystem +# has completed writing the files, etc. Sometimes we get here before +# all the files have finished being written. +#----------------------------------------------------------------------------- + +echo "Listing contents of CENTRALDIR before archiving" +ls -l + +exit + +${MOVE} *.data *.meta ${experiment}/POP +${MOVE} data data.cal ${experiment}/POP +${MOVE} STD* ${experiment}/POP + +${MOVE} filter_restart* ${experiment}/DART +${MOVE} assim_model_state_ud[1-9]* ${experiment}/DART +${MOVE} assim_model_state_ic[1-9]* ${experiment}/DART +${MOVE} Posterior_Diag.nc ${experiment}/DART +${MOVE} Prior_Diag.nc ${experiment}/DART +${MOVE} obs_seq.final ${experiment}/DART +${MOVE} dart_log.out ${experiment}/DART + +# Good style dictates that you save the scripts so you can see what worked. + +${COPY} input.nml ${experiment}/DART +${COPY} *.csh ${experiment}/DART +${COPY} $myname ${experiment}/DART + +ls -lrt Property changes on: DART/trunk/models/POP/shell_scripts/run_perfect_model_obs.batch ___________________________________________________________________ Name: svn:executable + * Added: DART/trunk/models/POP/work/README =================================================================== --- DART/trunk/models/POP/work/README (rev 0) +++ DART/trunk/models/POP/work/README 2009-08-31 21:25:29 UTC (rev 4025) @@ -0,0 +1,48 @@ +create_obs_sequence parameters: + Input upper bound on number of observations in sequence : 10 + Input number of copies of data (0 for just a definition): 0 + Input number of quality control values per field (0 or greater): 0 + input a -1 if there are no more obs: 0 + + Input -1 * state variable index for identity observations + OR input the name of the observation kind from table below: + OR input the integer index, BUT see documentation... + 1 SALINITY + 2 TEMPERATURE + 3 U_CURRENT_COMPONENT + 4 V_CURRENT_COMPONENT + 5 SEA_SURFACE_HEIGHT +2 + location_mod:initialize_module vert-normalization 20.0000000000000 100000.000000000 10000.0000000000 + location_mod:initialize_module horizontal only T + Vertical co-ordinate options + -2 --> vertical coordinate undefined + -1 --> surface + 1 --> model level + 2 --> pressure + 3 --> height +3 + Vertical co-ordinate height : 23.0 + Input longitude: value 0 to 360.0 or a negative number for + Uniformly distributed random location in the horizontal: 315 + Input latitude: value -90.0 to 90.0: 30 + input time in days and seconds (as integers): 8760 0 + Input error variance for this observation definition : 2.0 + input a -1 if there are no more obs : -1 + Input filename for sequence ( set_def.out usually works well): set_def.out + +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- + +create_fixed_network_sequence + +set_def.out +1 +1 +8760 0 +1 0 +obs_seq.in + + + + Modified: DART/trunk/models/POP/work/input.nml =================================================================== --- DART/trunk/models/POP/work/input.nml 2009-08-28 22:46:16 UTC (rev 4024) +++ DART/trunk/models/POP/work/input.nml 2009-08-31 21:25:29 UTC (rev 4025) @@ -20,7 +20,7 @@ &filter_nml async = 2, adv_ens_command = "./advance_model.csh", - ens_size = 8, + ens_size = 10, start_from_restart = .false., output_restart = .true., obs_sequence_in_name = "obs_seq.perfect", @@ -78,7 +78,7 @@ &ensemble_manager_nml single_restart_file_in = .true., - single_restart_file_out = .true., + single_restart_file_out = .false., perturbation_amplitude = 0.2 / &cov_cutoff_nml