| Jump to DART Documentation Main Index |
The DART system supports data assimilation into the Community Atmosphere Model, CAM, which is the atmospheric component of the Community Earth System Model (CESM). This DART interface is being used by graduate students, post-graduates, and scientists at universities and research labs to conduct data assimilation reseearch. Others are using the products of data assimilation (analyses), which were produced here at NCAR using CESM+DART, to conduct related research. The variety of research can be sampled on the DART Publications page.
"CAM" refers to a family of related atmospheric components, which can be built with 2 independent main characteristics. CESM labels these as:
'resolution' = horizontal (not vertical) grid AND dynamical core (fluid dynamics equations on that grid) 3 supported dycores; eulerian, FV, and SE SE refined grids will have some support, but by their nature invite the use of user defined grid and map files. 'compset' = vertical grid AND parameterizations (aka physics): Parameterization is the equations describing a physical process like convection, radiation, chemistry, ... Vertical grid is determined by the needs of the chosen parameterizations. Spacing and height of the top (ptop) vary. The combinations of parameterizations and vertical grids are named: CAM3.5, CAM5, CAM#, ... WACCM, WACCM#, WACCM-X, CAM-Chem, ...There are minor characteristics choices within each of these, but only chemistry choices in WACCM and CAM-Chem have an impact on DART. As of April, 2015, all of these variants are handled by the same model_mod.f90, namelist, and build scripts, with differences in the assimilation set up described here. This DART+CAM interface has the following features.
In addition to the standard DART package there are ensembles of initial condition files at the large file website http://www.image.ucar.edu/pub/DART/CAM/ that are helpful for interfacing CAM with DART. In the current (2015) mode, CESM+DART can easily be started from a single model state, which is perturbed to create an ensemble of the desired size. A spin-up period is then required to allow the ensemble members to diverge.
Sample sets of observations, which can be used with CESM+DART assimilations, can be found at http://www.image.ucar.edu/pub/DART/Obs_sets/ of which the NCEP BUFR observations are the most widely used.
Experience on a variety of machines has shown that it is a very good idea to make sure your run-time environment has the following:
limit stacksize unlimited limit datasize unlimited
This page contains the documentation for the DART interface module for the CAM and WACCM models, using the dynamical cores listed above. This implementation uses the CAM initial files (not restarts) for transferring the model state to/from the filter. This may change in future versions, but probably only for CAM-SE. The reasons for this include:
The DART interfaces to CAM and many of the other CESM components have been integrated with the CESM set-up and run scripts. Unlike previous versions of DART-CAM, CESM runs using its normal scripts, then stops and calls a DART script, which runs a single assimilation step, then returns to the CESM run script to continue the model advances. See the CESM interface documentation for more information on running DART with CESM. Due to the complexity of the CESM software environment, the versions of CESM which can be used for assimilation are more restricted than previously. Each supported CESM version has similar, but unique, sets of set-up scripts and CESM SourceMods. Those generally do not affect the cam/model_mod.f90 interface. Current (April, 2015) set-up scripts are:
The DART state vector should include all prognostic variables in the CAM initial files which cannot be calculated directly from other prognostic variables. In practice the state vector sometimes contains derived quantities to enable DART to compute forward operators (expected observation values) efficiently. The derived quantities are often overwritten when the model runs the next timestep, so the work DART does to update them is wasted work.
Expected observation values on pressure, scale height, height or model levels can be requested from model_interpolate. Surface observations can not yet be interpolated, due to the difference between the model surface and the earth's surface where the observations are made. Model_interpolate can be queried for any (non-surface) variable in the state vector (which are variables native to CAM) plus pressure on height levels. The default state vector is PS, T, U, V, Q, CLDLIQ, CLDICE and any tracers or chemicals needed for a given study. Variables which are not in the initial file can be added, but minor modifications to model_mod.f90 and CAM may be necessary.
The 19 public interfaces in model_mod are standardized for all DART compliant models. These interfaces allow DART to get the model state and metadata describing this state, find state variables that are close to a given location, and do spatial interpolation for a variety of variables required by observational operators.
This namelist is read from the file input.nml. Namelists start with an ampersand '&' and terminate with a slash '/'. Character strings that contain a '/' must be enclosed in quotes to prevent them from prematurely terminating the namelist. The values shown here are the default values.
&model_nml cam_template_filename = 'caminput.nc' cam_phis_filename = 'cam_phis.nc' vertical_localization_coord = 'PRESSURE' use_log_vertical_scale = .false. no_normalization_of_scale_heights = .true. no_obs_assim_above_level = -1, model_damping_ends_at_level = -1, state_variables = '' assimilation_period_days = 0 assimilation_period_seconds = 21600 suppress_grid_info_in_output = .false. custom_routine_to_generate_ensemble = .true. fields_to_perturb = '' perturbation_amplitude = 0.0_r8 using_chemistry = .false. use_variable_mean_mass = .false. debug_level = 0 /
The names of the fields to put into the state vector must match the CAM initial NetCDF file variable names.
| Item | Type | Description |
|---|---|---|
| cam_template_file | character(len=128) | CAM initial file used to provide configuration information, such as the grid resolution, number of vertical levels, whether fields are staggered or not, etc. |
| cam_phis | character(len=128) | CAM topography file. Reads the "PHIS" NetCDF variable from this file. Typically this is a CAM History file because this field is not normally found in a CAM initial file. |
| vertical_localization_coord | character(len=128) | The vertical coordinate to which all vertical locations are converted in model_mod. Valid options are "pressure", "height", "scaleheight" or "level". |
| no_normalization_of_scale_heights | logical | If true the scale height is computed as the log of the pressure at the given location. If false the scale height is computed as a ratio of the log of the surface pressure and the log of the pressure aloft. In limited areas of high topography the ratio version might be advantageous, and in previous versions of filter this was the default. For global CAM the recommendation is to set this to .true. so the scale height is simply the log of the pressure at any location. |
| no_obs_assim_above_level | integer | Because the top of the model is highly damped it is recommended to NOT assimilate observations in the top model levels. The units here are CAM model level numbers. Set it to equal or below the lowest model level (the highest number) where damping is applied in the model. |
| model_damping_ends_at_level | integer | Set this to the lowest model level (the highest number) where model damping is applied. Observations below the 'no_obs_assim_above_level' cutoff but close enough to the model top to have an impact during the assimilation will have their impacts decreased smoothly to 0 at this given model level. The assimilation should make no changes to the model state above the given level. |
| state_variables | character(len=64), dimension(100) | Character string table that includes: Names of fields (NetCDF variable names) to be read into the state vector, the corresponding DART Quantity for that variable, if a bounded quantity the minimum and maximum valid values, and finally the string 'UPDATE' to indicate the updated values should be written back to the output file. 'NOUPDATE' will skip writing this field at the end of the assimilation. |
| assimilation_period_days | integer | Sets the assimilation window width, and should match the model advance time when cycling. The scripts distributed with DART always set this to 0 days, 21600 seconds (6 hours). |
| assimilation_period_seconds | integer | Sets the assimilation window width, and should match the model advance time when cycling. The scripts distributed with DART always set this to 0 days, 21600 seconds (6 hours). |
| suppress_grid_info_in_output | logical | Filter can update fields in existing files or create diagnostic/output files from scratch. By default files created from scratch include a full set of CAM grid information to make the file fully self-contained and plottable. However, to save disk space the grid variables can be suppressed in files created by filter by setting this to true. |
| custom_routine_to_generate_ensemble | logical | The default perturbation routine in filter adds gaussian noise equally to all fields in the state vector. It is recommended to set this option to true so code in the model_mod is called instead. This allows only a limited number of fields to be perturbed. For example, only perturbing the temperature field T with a small amount of noise and then running the model forward for a few days is often a recommended way to generate an ensemble from a single state. |
| fields_to_perturb | character(len=32), dimension(100) | If perturbing a single state to generate an ensemble, set 'custom_routine_to_generate_ensemble = .true.' and list list the field(s) to be perturbed here. |
| perturbation_amplitude | real(r8), dimension(100) | For each field name in the 'fields_to_perturb' list give the standard deviation for the gaussian noise to add to each field being perturbed. |
| pert_base_vals | real(r8), dimension(100) | If pert_sd is positive, this the list of values to which the field(s) listed in pert_names will be reset if filter is told to create an ensemble from a single state vector. Otherwise, it's is the list of values to use for each ensemble member when perturbing the single field named in pert_names. Unused unless pert_names is set and pert_base_vals is not the DART missing value. |
| using_chemistry | logical | If using CAM-CHEM, set this to .true. |
| using_variable_mean_mass | logical | If using any variant of WACCM with a very high model top, set this to .true. |
| debug_level | integer | Set this to increasingly larger values to print out more debugging information. Note that this can be very verbose. Use with care. |
The variants of CAM require slight changes to the setup scripts (in $DART/models/cam/shell_scripts) and in the namelists (in $DART/models/cam/work/input.nml). From the DART side, assimilations can be started from a pre-existing ensemble, or an ensemble can be created from a single initial file before the first assimilation. In addition, there are setup differences between 'perfect model' runs, which are used to generate synthetic observations, and assimilation runs. Those differences are extensive enough that they've been coded into separate setup scripts:
Since the CESM compset and resolution, and the initial ensemble source are essentially independent of each other, changes for each of those may need to be combined to perform the desired setup.
:The default values in work/input.nml and shell_scripts/CESM1_2_1_setup_{pmo,hybrid} are set up for a CAM-FV, single assimilation cycle using the default values as found in model_mod.f90 and starting from a single model state, which must be perturbed into an ensemble. The following are suggestions for setting it up for other assimilations. Namelist variables listed here might be in any namelist within input.nml.
If built with the FV dy-core, the number of model top levels with extra diffusion in CAM is controlled by div24del2flag. The recommended minium values of highest_state_pressure_Pa come from that variable, and cutoff*vert_normalization_X:
2 ("div2") -> 2 levels -> highest_state_pressure_Pa = 9400. Pa 4,24 ("del2") -> 3 levels -> highest_state_pressure_Pa = 10500. Pa
vert_coord = 'pressure' state_num_1d = 0, state_num_2d = 1, state_num_3d = 6, state_names_1d = '' state_names_2d = 'PS' state_names_3d = 'T', 'US', 'VS', 'Q', 'CLDLIQ', 'CLDICE' which_vert_1d = 0, which_vert_2d = -1, which_vert_3d = 6*1, highest_state_pressure_Pa = 9400. or 10500.
There's an existing ensemble, so see Continuing to start from it instead of a single state. To set up a "1-degree" CAM-SE assimilation CESM1_2_1_setup_hybrid:
setenv resolution ne30_g16 setenv refcase SE30_Og16 setenv refyear 2005 setenv refmon 08 setenv refday 01input.nml:
approximate_distance = .FALSE. vert_coord = 'pressure' state_num_1d = 1, state_num_2d = 6, state_num_3d = 0, state_names_1d = 'PS' state_names_2d = 'T','U','V','Q','CLDLIQ','CLDICE' state_names_3d = '' which_vert_1d = -1, which_vert_2d = 6*1, which_vert_3d = 0, highest_obs_pressure_Pa = 1000., highest_state_pressure_Pa = 10500.,
To set up a variable resolution CAM-SE assimilation (as of April 2015) there are many changes to both the CESM code tree and the DART setup scripts. This is for very advanced users, so please contact dart @ ucar dot edu or raeder @ ucar dot edu for scripts and guidance.
WACCM[#][-X] has a much higher top than the CAM versions, which requires the use of scale height as the vertical coordinate, instead of pressure, during assimilation. One impact of the high top is that the number of top model levels with extra diffusion in the FV version is different than in the low-topped CAM-FV, so the div24del2flag options lead to the following minimum values for highest_state_pressure_Pa:
2 ("div2") -> 3 levels -> highest_state_pressure_Pa = 0.01 Pa 4,24 ("del2") -> 4 levels -> highest_state_pressure_Pa = 0.02 PaThe best choices of vert_normalization_scale_height, cutoff, and highest_state_pressure_Pa are still being investigated (April, 2015), and may depend on the observation distribution being assimilated.
WACCM is also typically run with coarser horizontal resolution. There's an existing 2-degree ensemble, so see Continuing to start from it, instead of a single state. If you use this, ignore any existing inflation restart file and tell DART to make its own in the first cycle in input.nml:
inf_initial_from_restart = .false., .false., inf_sd_initial_from_restart = .false., .false.,
In any case, make the following changes (or similar) to convert from a CAM setup to a WACCM setup. CESM1_2_1_setup_hybrid:
setenv compset F_2000_WACCM setenv resolution f19_f19 setenv refcase FV1.9x2.5_WACCM4 setenv refyear 2008 setenv refmon 12 setenv refday 20input.nml:
vert_normalization_scale_height = 2.5 vert_coord = 'log_invP' highest_obs_pressure_Pa = .001, highest_state_pressure_Pa = .01,If built with the SE dy-core (warning; experimental), then 4 levels will have extra diffusion, and also see here.
If there are problems with instability in the WACCM foreasts, try changing some of the following parameters in either the user_nl_cam section of the setup script or input.nml.
echo " div24del2flag = 2 " >> ${fname}which will use the cd_core.F90 in SourceMods, which has doubled diffusion in the top layers compared to CAM.
echo " dtime = 600 " >> ${fname}
div24del2flag = 2 ("div2") -> highest_state_pressure_Pa = 0.1 Pa div24del2flag = 4,24 ("del2") -> highest_state_pressure_Pa = 0.2 Pa
echo " nsplit = 16 " >> ${fname} echo " nspltvrm = 4 " >> ${fname}
inf_damping = 0.5, 0,
After the first forecast+assimilation cycle, using an ensemble created from a single file, it is necessary to change to the 'continuing' mode, where CAM will not perform all of its startup procedures and DART will use the most recent ensemble. This example applies to an assimiation using prior inflation (inf_... = .true.). If posterior inflation were needed, then the 2nd column of infl_... would be set to "true".
input.nml: start_from_restart = .true., restart_in_file_name = "filter_ics", single_restart_file_in = .false., inf_initial_from_restart = .true., .false., inf_sd_initial_from_restart = .true., .false.,
CESM1_2_1_setup_{hybrid,pmo} are set up in the default cycling mode, where each submitted job performs one model advance and one assimilation, then resubmits the next cycle as a new job. For long series of cycles, this can result in a lot of time waiting in the queue for short jobs to run. This can be prevented by using the 'cycles' scripts generated by CESM1_2_1_setup_advanced (instead of ..._hybrid). This mode is described in the models/cam/doc/README.
mpi_utilities_mod netcdf obs_kind_mod random_seq_mod threed_cartesian/xyz_location_mod threed_sphere/location_mod time_manager_mod types_mod typeSizes utilities_mod
Here they are listed alphabetically, except for the last 4 interfaces, which are only required for low-order models where advancing the model can be done by a call to a subroutine. The last 4 interfaces only appear as stubs in the CAM module. Following this list they are listed in the order in which they appear in model_mod.f90, which is separated into sections corresponding to the main functions of model_mod.f90: static_init_model, I/O, model_interpolate, vector<->field translations, get_close_obs, and utility routines.
The interface pert_model_state is provided for CAM, and it allows each field of the state vector to be randomly perturbed using a separate standard deviation. Even this may not be flexible enough to handle variables such as specific humidity, which can vary by orders of magnitude from the surface to the top of the model.
The list of interfaces above is part of the list of public routines in this module. The rest of the public list are used by programs other than filter; dart_to_cam, cam_to_dart, etc.
| use model_mod, only : | model_type |
| prog_var_to_vector | |
| read_cam_init | |
| vector_to_prog_var | |
| write_cam_init |
Namelist interface &model_nml is read from file input.nml.
A type for the CAM model. It consists of pointers to model variables having ranks (non-time dimensions) of 0...3. Note that CAM-SE fields have rank = spatial_dims - 1.
Used for run time initialization of the model. This is the first call made to the model by any DART compliant assimilation routine. It reads the model_mod namelist parameters, sets the calendar type (the GREGORIAN calendar is used with the CAM model), and determines the dart vector length, among other things. This subroutine requires that caminput.nc, (or the names in namelist variable model_config_file) be present in the working directory to retrieve model information (grid dimensions and spacing including the vertical hybrid coordinate coefficients, time step, and Gaussian weights, etc).
integer, intent(in) :: index_in type(location_type), intent(out) :: location integer, optional, intent(out) :: var_kind
Returns metadata about a given element, indexed by index_in, in the model state vector. The location defines where the state variable is located while the DART KIND of the variable (for instance temperature, or u wind component) is returned by var_kind.
| index_in | Index into the long state vector. |
| location | Returns location of indexed state variable. The location should use a location_mod that is appropriate for the model domain. For realistic atmospheric models, for instance, a three-dimensional spherical location module that can represent height in a variety of ways is provided. |
| var_kind | Returns the type of the indexed state variable as an optional argument. |
real(r8), dimension(:), intent(in) :: ens_mean
Saves a local copy of the ensemble means which can be used for computing vertical heights, for example.
| ens_mean | Ensemble mean state vector |
integer :: get_model_size
Returns the length of the model state vector as an integer.
type(time_type) :: get_model_time_step
Returns the nominal useful forecast length for CAM,
not CAM's internal time step (dtime).
get_model_time_step is set by the
input.nml
&model_nml:Time_step_seconds,Time_step_days
get_model_time_step also indirectly defines the assimilation window.
Every observation within +/- half the get_model_time_step
of the current model time will be assimilated.
The current CESM+DART setup scripts also implicitly use this to determine which
set of observations to use. If the observation sequence file has observations
beyond the end of the current assimilation window, DART will try to advance
CAM. This is not supported under the current configuration. Similarly, if the
observation sequence file has observations before the assimilation window,
DART will fail because it cannot move the model backwards in time.
Consequently, the observation sequence files have to be preprocessed to
contain just the observations to be assimilated without advancing the model.
integer, :: nc_write_model_atts integer, intent(in) :: ncFileId
Function to write model specific attributes to a netCDF file identified by ncFileID. DART uses the NetCDF format to output assimilation diagnostic information.
| ncFileId | Integer file descriptor opened to NetCDF file. |
| ierr | Returned error code. |
integer :: nc_write_model_vars integer, intent(in) :: ncFileID real(r8), dimension(:), intent(in) :: statevec integer, intent(in) :: copyindex integer, intent(in) :: timeindex
Writes a copy of the state variables to a NetCDF file. Multiple copies of the state for a given time are supported, allowing, for instance, a single file to include multiple ensemble estimates of the state.
| ncFileID | Integer file descriptor to opened NetCDF file. |
| statevec | State vector. |
| copyindex | Integer index to which copy is to be written. |
| timeindex | Integer index of which time in the file is being written. |
| ierr | Returned error code. success == 0, failure == -1 |
character(len, intent(in) :: file_name type(model_type), intent(out) :: var
Reads state vector fields from a CAM initial file. Fields are specified in model_mod.nml.
| file_name | CAM initial file name. |
| var | Structure to hold the state vector fields read from file_name. |
character, intent(in) :: file_name type(time_type), intent(in) :: model_time type(model_type), allocatable, intent(in) :: var
Write fields that have been updated by assimilation to the CAM 'initial' file.
| file_name | Name of CAM initial file to which CAM state 'var' will be written. |
| model_time | Time of state to be written. |
| var | Structure containing all the fields of the state vector. |
real(r8), dimension(:), intent(in) :: st_vec type(location_type), intent(in) :: location integer, intent(in) :: obs_kind real(r8), intent(out) :: interp_val integer, intent(out) :: istatus
Given a model state, returns the value of the variable encoded in obs_kind interpolated to a given location by a method of the model's choosing. Currently DART KINDs: QTY_U_WIND_COMPONENT, QTY_V_WIND_COMPONENT, QTY_SURFACE_PRESSURE, QTY_TEMPERATURE, QTY_SPECIFIC_HUMIDITY, QTY_PRESSURE are supported, but others can be added. QTY_PRESSURE does not have a corresponding field on CAM initial files, but is routinely calculated in CAM using its own subroutines. Interpolation of this field has been incorporated in order to facilitate assimilations of observations which require it, such as GPS radio occultation. CAM-SE requires a completely different interpolation algorithm from the logically rectangular grids of the eulerian and FV dycores. So model_interpolate is now simply calls either interp_lonlat or interp_cubed_sphere.
If the interpolation is valid, istatus = 0. In the case where the observational operator is not defined at the given location (e.g. the observation is below the lowest model level or above the top level), interp_val is returned as MISSING_R8 and istatus > 0. CAM is highly damped in the upper levels of the model, which may require the exclusion of otherwise valid observations above a certain level, which can be specified in the model_mod namelist variable highest_obs_pressure_Pa . Such cases return istatus = 2, and also do the interpolation and return the value, which is NOT used by filter. Eventually such quality control may be moved to another module, but for now is performed in subroutine get_val_pressure. DART reserves the use of istatus < 0.
| st_vec | Model state vector. |
| location | Location to which to interpolate. |
| obs_kind | Integer indexing which type of observation is to be interpolated. |
| interp_val | Value interpolated to location. |
| istatus | Integer flag indicating the success of the interpolation. |
real(r8), intent(in) :: a, b, c real(r8), intent(out) :: r1, r2
Calculate the roots (r1, r2) of the quadratic equation defined by coefficients a, b, and c.
real(r8), intent(in) :: st_vec(:) type(location_type), intent(in) :: location integer, intent(in) :: obs_kind real(r8), intent(out) :: interp_val integer, intent(out) :: istatus
Find the 8 corners of the lon-lat-lev grid cell, which encloses an observation at 'location', and interpolate the values of variable 'obs_kind' to that location. Variables defined as in model_interpolate.
type(model_type), allocatable, intent(in) :: var real(r8), allocatable, dimension(:), intent(out) :: x
Insert CAM fields (N-Dimensional) into DART state vector array (1-D)
| var | Structure containing all the fields of the state vector. |
| x | DART state vector. |
real(r8), allocatable, dimension(:), intent(in) :: x type(model_type), allocatable, intent(out) :: var
Extract CAM fields (N-Dimensional) from state vector (1-D).
| x | DART state vector. |
| var | Structure containing all the fields of the state vector. |
type(get_close_type), intent(in) :: filt_gc type(location_type), intent(in) :: base_obs_loc integer, intent(in) :: base_obs_kind type(location_type), intent(in) :: obs(:) integer, intent(in) :: obs_kind(:) integer, intent(out) :: num_close integer, intent(out) :: close_ind(:) real(r8), optional, intent(out) :: dist(:)
First calls the location_mod:get_close_obs() and then updates the distances to account for the extra diffusion in CAM's highest levels.
CAM uses a hybrid vertical coordinate, which requires the surface pressure
beneath a point in order to determine the point's vertical location.
The ensemble members may each have a different surface pressure,
which could cause an observation to have different distances
to the surrounding grid points.
This can cause the observation to be excluded
(distance > 2*cutoff)
in some members, but not others, which is an ambiguity we'd like to avoid.
The ensemble mean state is used to a provide a consistent
vertical location for the whole ensemble.
All observations on height and level are handled automatically, using the
ensemble mean for calculations.
Due to the extra diffusion at high levels in CAM
(see model_interpolate)
there is also code
which reduces the influence of all observations on model points above some altitude.
Currently namelist variable
highest_state_pressure_Pa controls this.
The default value in model_mod (for CAM), and the values for WACCM given in
model_top_issues.pdf,
gradually reduce the influence of observations from full strength at
highest_state_pressure_Pa
to 0 at the model levels where extra diffusion is applied (2 or 3 for CAM,
3 or 4 for WACCM).
type(get_close_type), intent(inout) :: gc real(r8), intent(in) :: maxdist
Pass-through to the 3-D sphere locations module routine of the same name. See location_mod:get_close_maxdist_init() for the documentation of this subroutine.
| gc | A get_close type whose maxdist will be defined here. |
| maxdist | The maximum distance around a location at which a lon-lat grid box can be considered close to a location. |
type(get_close_type), intent(inout) :: gc integer, intent(in) :: num type(location_type), intent(in) :: obs(num)
Pass-through to the 3-D sphere locations module. See location_mod:get_close_obs_init() for the documentation of this subroutine.
real(r8), dimension(:), intent(in) :: state real(r8), dimension(:), intent(out) :: pert_state logical, intent(out) :: interf_provided
Given a model state, produces a perturbed model state. This is used to generate ensemble initial conditions perturbed around some control trajectory state when one is preparing to spin-up ensembles. interf_provided is .true. for this cam/model_mod.f90.
This implementation allows each field in the state vector to be randomly perturbed with a separate standard deviation. The fields to be perturbed, and the associated standard deviations are specified in the model_mod namelist using state_names_pert and state_names_sd. The entries in state_names_pert should be in the same order as those in state_names_#d (# = 0,1,2,3 in that order). As in the default, the perturbations sd*N[0,1] are added onto the basic state field, so sd should not be a percentage of the basic state field, but an actual physical size.
| state | State vector to be perturbed. |
| pert_state | Perturbed state vector is returned. |
| interf_provided | Return false to have DART perturb state . |
real(r8), dimension(:), intent(inout) :: x type(time_type), intent(in) :: time
This operation is not defined for the CAM model. This interface is only required if `synchronous' model state advance is supported (the model is called directly as a Fortran90 subroutine from the assimilation programs). This is generally not the preferred method for large models and a stub for this interface is provided for the CAM model.
| x | State vector of length model_size. |
| time | Gives time of the initial model state. Needed for models that have real time state requirements, for instance the computation of radiational parameters. Note that DART provides a time_manager_mod module that is used to support time computations throughout the facility. |
Called when use of a model is completed to clean up storage, etc.
type(time_type), intent(out) :: time
Returns the time at which the model will start if no input initial conditions are to be used. This is frequently used to spin-up models from rest, but is not meaningfully supported for the CAM model.
real(r8), dimension(:), intent(out) :: x
Returns default initial conditions for model; generally used for spinning up initial model states. For the CAM model it's just a stub because initial state is always to be provided from input files.
| x | Model state vector. |
Here they are listed alphabetically. Following this list they are listed in the order in which they appear in model_mod.f90, which is separated into sections corresponding to the main functions of model_mod.f90: static_init_model, I/O, model_interpolate, vector<->field translations, get_close_obs, and utility routines.
integer, intent(out) :: ncfileid
Gets the number of lons, lats and levels from a netcdf CAM initial file and stores in global storage.
| ncfileid | NetCDF file ID for CAM the initial file. |
integer, intent(in) :: ncfileid
Rearranges sizes of the coordinates of each variable as found on caminput.nc file (stored in variable f_dim_#d) into the order model_mod wants to see them for the state (s_dim_#d); lev, lon, lat. # = 1,2,3 for the numbers of dimensions of the variables.
| ncfileid | The file ID number of the caminput.nc file. |
Uses the model_version from input.nml:model_nml to figure out the order of lev, lat, and lon on the caminput.nc file. Designed to be flexible enough to handle staggered and unstaggered U and V, 2D fields which may be (lev,lat) instead of (lon,lat), and unstructured grids which may come from HOMME or the CLM.
character, len=*, intent(in) :: file_name character, len=8, intent(in) :: cfield
Read a 2-D field from a NetCDF file, so far just surface height (phis) from cam_phis.nc.
| file_name | The name of the file file containing field "cfield". |
| cfield | Name of the field (on the file) to be read. |
character, intent(in) :: att character, dimension(:), intent(out) :: att_vals integer, intent(in) :: nflds
Reads the value of an attribute for each of the fields in cflds.
| att | The name of an attribute of the fields on a CAM initial file. |
| att_vals | The values which that attribute has for each of the nflds fields needed for the state vector. |
| nflds | The number of fields in the state vector. |
integer, intent(in) :: ncFileID character (len=*), intent(in) :: att integer, intent(out) :: att_val
Reads the value of a global attribute. Needed to get grid information from CAM-SE (cubed sphere) initial files.
| ncFileID | The NetCDF identifier of the file on which to find the attribute. |
| att | The name of the global attribute. |
| att_val | The value of the attribute. |
integer, intent(in) :: ncfileid character(len=8), intent(in) :: cfield type(grid_1d_type), intent(out) :: var
Reads a coordinate array and metadata from a CAM initial file.
| ncfileid | Length of var. |
| cfield | Name of var, as found on the CAM initial file. |
| var | A coordinate array from a CAM initial file. |
integer, intent(in ) :: length integer, intent(in ) :: num_atts type(grid_1d_type), intent(inout) :: var
Allocate space for the variable of defined type grid_1d_type. Put vector length and the number of attributes in structure. These are coordinate variables read from caminput.nc, and have lots of characteristics which are helpful to keep together in one structure. The rest of var is filled in read_cam_coord.
| length | The length of var. |
| num_atts | The number of attributes of this coordinate, from caminput.nc. |
| var | The coordinate variable to read from caminput.nc. |
type grid_1d_type private character (len=8) :: label ! e.g. 'lat ' integer :: dim_id ! NetCDF dimension ID from the file integer :: length ! number of elements in the coordinate array real(r8) :: resolution ! spacing between elements, or 0. for irreg. real(r8), allocatable :: vals(:) ! coordinate values integer :: num_atts ! number of NetCDF attributes character (len=NF90_MAX_NAME), allocatable :: atts_names(:) ! names of those attributes character (len=NF90_MAX_NAME), allocatable :: atts_vals(:) ! values of those attributes end type grid_1d_type
type(grid_1d_type), intent(inout) :: var
Deallocate the array components of the variable of defined type grid_1d_type.
| var | Coordinate variable and metadata. |
Fills cflds with state_names for use in I/O of caminput.nc Also assigns field TYPE_ variables for use by get_state_meta_data, and other routines.
Makes an array (dart_to_cam_types) of 'locations within the state vector' of all the available obs KINDs that come from obs_kind_mod. Also maps the local model_mod TYPEs onto the DART KINDs by the same mechanism.
The obs kind that's needed will be the index into this array, the corresponding value will be the position of that field (not individual variable) within the state vector according to state_name_Xd. This subroutine is called from static_init_model, and arrays dart_to_cam_types and cam_to_dart_kinds are global, so they will not have to be recomputed for every obs.
Checks the values of several of the variables read from input.nml:model_nml.
integer, intent(in) :: ncFileID character (len=8), intent(in) :: c_name type(grid_1d_type), intent(in) :: coord integer, intent(in) :: dim_id integer, intent(out) :: c_id
Define a coordinate variable on the P[oste]rior_Diag.nc file and write some of its attributes there.
| ncFileID | Integer ID number of the NetCDF file. |
| c_name | Coordinate name. |
| coord | Coordinate values and metadata. |
| dim_id | The dimension ID of the coordinate on the NetCDF file. |
| c_id | Coordinate variable ID number on the NetCDF file. |
real(r8), intent(in), allocatable, dimension(:) :: st_vec integer, intent(in) :: lon_index integer, intent(in) :: lat_index integer, intent(in) :: level_index integer, intent(in) :: obs_kind real(r8), intent(out) :: val integer, intent(out) :: istatus
Gets the value on the model level for variable obs_kind at the lon_index, lat_index horizontal grid point. Some observations may be excluded here by model_nml restrictions. For examples, observations below the lowest model level are excluded, including surface pressure. So are observations above the lower of highest_obs_pressure_Pa and the model's highest level.
| st_vec | DART state vector. |
| lon_index | Index of longitude of this val. |
| lat_index | Index of latitude of this val. |
| level_index | Index of the level for which this obs_kind must be retrieved. |
| obs_kind | The DART KIND of variable being interpolated, e.g. QTY_TEMPERATURE. |
| val | The value of the obs_kind variable interpolated from state vector x. |
| istatus | Flag containing the status of the interpolation. 0; all good, 1; can't interpolate, 2; can interpolate but don't use the value, < 0; reserved for DART library use. |
real(r8), intent(in), allocatable, dimension(:) :: st_vec integer, intent(in) :: lon_index integer, intent(in) :: lat_index real(r8), intent(in) :: pressure integer, intent(in) :: obs_kind real(r8), intent(out) :: val integer, intent(out) :: istatus
Gets the vertically interpolated value on pressure for variable obs_kind at the lon_index, lat_index horizontal grid point. Some quality control of observations is done here, but may be moved later. For now, observations above the lower of highest_obs_pressure_Pa and the model's highest level, and below the lowest model level are excluded.
| val | The value of the obs_kind variable interpolated from state vector. |
| st_vec | DART state vector. |
| lon_index | Index of longitude of this val. |
| lat_index | Index of latitude of this val. |
| pressure | The pressure to which this obs_kind must be interpolated. |
| obs_kind | The kind of variable being interpolated, i.e. T. |
| istatus | Flag containing the status of the interpolation. 0; all good, 1; can't interpolate, 2; can interpolate but don't use the value, < 0; reserved for DART library use. |
real(r8), intent(in), allocatable, dimension(:) :: st_vec integer, intent(in) :: lon_index integer, intent(in) :: lat_index real(r8), intent(in) :: height integer, intent(in) :: obs_kind real(r8), intent(out) :: val integer, intent(out) :: istatus
Gets the vertically interpolated value on height for variable obs_kind at the lon_index, lat_index horizontal grid point. Some quality control of observations is done here, but may be moved later. For now, observations above the lower of highest_obs_height_m and the model's highest level, and below the lowest model level are excluded.
| val | The value of the obs_kind variable interpolated from state vector st_vec. |
| st_vec | DART state vector. |
| lon_index | Index of longitude of this val. |
| lat_index | Index of latitude of this val. |
| height | The height to which this obs_kind must be interpolated. |
| obs_kind | The kind of variable being interpolated, i.e. T. |
| istatus | Flag containing the status of the interpolation. 0; all good, 1; can't interpolate, 2; can interpolate but don't use the value, < 0; reserved for DART library use. |
real(r8), intent(in), allocatable, dimension(:) :: st_vec integer, intent(in) :: lon_index integer, intent(in) :: lat_index integer, intent(in) :: level integer, intent(in) :: obs_kind real(r8), intent(out) :: val integer, intent(out) :: istatus
Extracts the value of a field at a specified location from the DART state vector.
| st_vec | DART state vector. |
| lon_index | Index of longitude of this val. |
| lat_index | Index of latitude of this val. |
| level | The level of the obs_kind variable desired. |
| obs_kind | The kind of variable being interpolated, i.e. T. |
| val | The value of the obs_kind variable at a grid point, from state vector x. |
| istatus | Flag containing the status of the interpolation. 0; all good, 1; can't interpolate, 2; can interpolate but don't use the value, < 0; reserved for DART library use. |
real(r8), dimension(3), intent(in) :: old_array integer, intent(in) :: old_which type(location_type), intent(in) :: old_loc integer, intent(in) :: old_kind real(r8), dimension(3), intent(inout) :: new_array integer, intent(out) :: new_which
Uses model information and subroutines to convert the vertical location of an observation (prior, model state variable, or actual ob) into the standard vertical coordinate (pressure or scale height). Accommodates staggered grid US and VS of the FV core.
| old_array | The location array of the incoming ob. |
| old_which | The vertical coordinate type of the incoming ob. |
| old_loc | The DART location of the incoming ob. |
| old_kind | The DART KIND of the incoming ob. |
| new_array | The location array of the converted ob. |
| new_which | The vertical coordinate type of the converted ob. |
Initialize the "get_close" structure for the cubed sphere grid. The structure is used to find a small set of candidate "close" nodes to a location.
real(r8), intent(in) :: lat, lon
Determine the index or name of the closest node (corner) to the given point.
| closest | The name of the cubed sphere node (cell corner) closest to (lon,lat). |
| lat, lon | The latitude and longitude (degrees) of the point of interest. |
integer, intent(in) :: lev_ind integer, intent(in) :: lon_ind integer, intent(in) :: lat_ind integer, intent(in) :: ifld integer :: index_from_grid
Function to generate the state vector index corresponding to the grid location and variable given.
| lev_ind | Level of the desired variable. |
| lon_ind | Longitude of the desired variable. |
| lat_ind | Latitude of the desired variable. |
| ifld | TYPE_ (PS or T or ...) index of the variable whose index is needed. |
Called by many routines.
character (len=*), intent(in) :: nam character (len=*), dimension(:),intent(in) :: list
Function to return the index of a character string as found within a list of character strings, typically variable or dimension names.
| nam | The string to be found within list. |
| list | The list which hopefully contains nam. |
character (len=*), intent(in) :: dim_name integer, intent(in) :: indx real(r8), intent(inout) :: lon_val real(r8), intent(inout) :: lat_val real(r8), intent(inout) :: lev_val
Given the name of the coordinate to be searched and the index into that array, returns the coordinate value in either lon_val, lat_val, or lev_val.
| dim_name | The name of the dimension being searched for the value at an index. |
| indx | The index of the variable whose location is needed. |
| lon_val | (Possibly) the location of the grid point in the longitudinal direction. |
| lat_val | (Possibly) the location of the grid point in the latitudinal direction. |
| lev_val | (Possibly) the location of the grid point in the vertical direction. |
All 3 _val arguments are present so that this routine can return the value in the coordinate that the calling routine wants it to be, and search/placement doesn't have to be done there. Used by get_state_meta_data and model_interpolate.
character (len=*), intent(in) :: dim_name real(r8), intent(in) :: val integer, intent(out) :: indx integer, optional, intent(out) :: other_indx
Given the name of the coordinate to be searched and the coordinate value, Returns the index of the closest coordinate value. Optionally returns the next closest index too, which may be < or > the closest.
| dim_name | The name of the dimension being searched for the value at an index. |
| val | The coordinate value whose nearest neighbors are needed. |
| indx | The index whose value is closest to val. |
| other_indx | The index whose value is 2nd closest to val. |
Used by get_state_meta_data. Uses coordinate metadata to search differently, depending on whether coordinate is regularly spaced or not.
real(r8), intent(in) :: vec(:)
Subroutine to put the ensemble average PS into a globally defined array. Also provides PS on the FV staggered grids, if needed.
| vec | The ensemble average state vector. |
real(r8), dimension(:), intent(in) :: p_surf integer, intent(in) :: num_levs real(r8), dimension(:), intent(out) :: pmid
Define the pressures of the CAM data levels (layer midpoints) from the coordinate definitions and the surface pressure.
| p_surf | Surface pressure at this latitude and longitude (Pa). |
| num_levs | Number of levels of pressures to calculate |
| pmid | Pressures at the CAM "midpoint" levels. |
integer, intent(in) :: num_levs real(r8), dimension(:), intent(in) :: vec real(r8), intent(in) :: p_surf type(location_type), intent(in) :: base_obs_loc real(r8), dimension(:), intent(out) :: model_h integer, intent(out) :: istatus
This routine calculates geometrical height (m) at mid-layers of the CAM model
| num_levs | Number of vertical levels. |
| vec | DART state vector. |
| p_surf | Surface pressure at this location. |
| base_obs_loc | The (horizontal) location at which heights will be calculated. |
| model_h | geometrical height at midlayer (m). |
| istatus | Status of the calculation returned to the calling routine. |
integer, intent(in) :: kmax real(r8), intent(in) :: p_surf real(r8), intent(in) :: phis0 real(r8), dimension(kmax), intent(in) :: tv real(r8), intent(in) :: hprb real(r8), dimension(2,kmax+1), intent(in) :: hybrid_As real(r8), dimension(2,kmax+1), intent(in) :: hybrid_Bs real(r8), dimension(kmax+1), intent(out) :: pmln real(r8), dimension(kmax), intent(out) :: pterm real(r8), dimension(kmax), intent(out) :: z2
Compute geopotential height for a CESM hybrid coordinate column. All arrays except hybrid_As, hybrid_Bs are oriented top to bottom. hybrid_[AB]s first subscript: = 1 for layer interfaces = 2 for layer midpoints hybrid_As coord coeffs for P0 reference pressure term in plevs_cam hybrid_Bs coord coeffs for surface pressure term in plevs_cam (in same format as hybrid_As)
| kmax | Number of vertical levels. |
| p_surf | Surface pressure (pascals). |
| phis0 | Surface geoptential. |
| tv | Virtual temperature, top to bottom. |
| hprb | Hybrid base pressure. |
| hybrid_As | Hybrid A coefficients (multiply P0). |
| hybrid_Bs | Hybrid B coefficients (multiply surface pressure). |
| pmln | Natural logs of midpoint pressures. |
| pterm | Pressure profile. |
| z2 | Geopotential height, top to bottom. |
real(r8), intent(out) :: gph2gmh real(r8), intent(in) :: h real(r8), intent(in) :: lat
Convert a geopotential altitude to mean sea level altitude.
| gph2gmh | MSL altitude, in km. |
| h | geopotential altitude (in km). |
| lat | latitude in degrees. |
real(r8), intent(in) :: xlat real(r8), intent(in) :: alt real(r8), intent(out) :: galt
This subroutine computes the Earth's gravity at any altitude and latitude (Bill Schreiner, May/1995). The model assumes the Earth is an oblate spheriod rotating at a the Earth's spin rate. The model was taken from "Geophysical Geodesy, Kurt Lambeck, 1988".
| xlat | latitude in radians. |
| alt | altitude above the reference ellipsiod, km. |
| galt | gravity at the given lat and alt, km/sec*sec. |
type(model_type), allocatable, intent(out) :: var
Initializes an instance of a cam model state variable; all the fields specified for the state vector.
| var | Structure which contains all the fields of various dimensions which are in the DART state vector. |
type model_type private real(r8), allocatable :: vars_0d(:) ! scalars real(r8), allocatable :: vars_1d(:, :) ! vectors real(r8), allocatable :: vars_2d(:, :, :) ! 2-D fields real(r8), allocatable :: vars_3d(:, :, :, :) ! 3-D fields end type model_type
type(model_type), allocatable, intent(inout) :: var
Ends an instance of a cam model_type state variable
| var | Structure which contains all the fields included in the state vector. |
Many CAM initial file variables are already handled in the model_mod. Here is a list of others, which may be used in the future. Each would need to have a DART KIND associated with it in model_mod.
Atmos CLOUD: "Cloud fraction" ; QCWAT: "q associated with cloud water" ; TCWAT: "T associated with cloud water" ; CWAT: "Total Grid box averaged Condensate Amount (liquid + ice)" ; also? LCWAT pbl PBLH: "PBL height" ; QPERT: "Perturbation specific humidity (eddies in PBL)" ; TPERT: "Perturbation temperature (eddies in PBL)" ; Surface LANDFRAC: "Fraction of sfc area covered by land" ; LANDM: "Land ocean transition mask: ocean (0), continent (1), transition (0-1)" ; also LANDM_COSLAT ICEFRAC: "Fraction of sfc area covered by sea-ice" ; SGH: "Standard deviation of orography" ; Z0FAC: "factor relating z0 to sdv of orography" ; TS: "Surface temperature (radiative)" ; TSOCN: "Ocean tempertare" ; TSICE: "Ice temperature" ; TSICERAD: "Radiatively equivalent ice temperature" ; Land/under surface SICTHK: "Sea ice thickness" ; SNOWHICE: "Water equivalent snow depth" ; TS1: "subsoil temperature" ; TS2: "subsoil temperature" ; TS3: "subsoil temperature" ; TS4: "subsoil temperature" ; Other fields are not included because they look more CLM oriented. Other fields which users may add to the CAM initial files are not listed here.
Ave Arellano did the first work with CAM-Chem, assimilating MOPPITT CO observations into CAM-Chem. Jerome Barre and Benjamin Gaubert took up the development work from Ave, and prompted several additions to DART, as well as cam/model_mod.
Nick Pedatella developed the first vert_coord = 'log_invP' capability to enable assimilation using WACCM and scale height vertical locations.
| Routine | Message | Comment |
|---|---|---|
| read_cam_init_size read_cam_init write_cam_init nc_read_model_atts nc_write_model_atts nc_write_model_vars read_cam_horiz read_cam_coord |
Various NetCDF-f90 interface error messages | From one of the NetCDF calls in the named routine |
| prog_var_to_vector vector_to_prog_var get_state_meta_data get_val model_get_close_states |
scalar and 1-D vector components of state vector are not coded into this routine | Only 2D and 3D fields can be part of state vector so far. |
| prog_var_to_vector vector_to_prog_var |
indx # and model_size # must be equal | indx was tallied during insertion of fields into state vector |
| model_get_close_states | which_vert = # not handled in model_get_close_states | See which_vert description in location/threed_sphere/location_mod.html |
| nc_write_model_atts | Time dimension ID # must match Unlimited Dimension ID # | NetCDF file writing error |
| order_state_fields | nfld = #, nflds = # must be equal | Mismatch(es) of state_names_#d and state_num_#d in model_nml |
The nonlocal GPS observation operator requires that highest_obs_pressure_Pa be ≤ 10000 Pa (100 mb). The local GPS observation operator doesn't have this restriction.
GPS observations require that highest_obs_pressure_Pa be <= 10000 Pa (100 mb).
- The coordinate orders and translations; CAM initial file, model_mod, and DART _Diag.nc. Motivations - There need to be 2 sets of arrays for dimensions and dimids; one describing the caminput file (f_...) and one for the state (s_...) (storage in this module). Call them f_dim_Nd , f_dimid_Nd s_dim_Nd , s_dimid_Nd
DART software - Copyright UCAR. This open source software is provided by UCAR, "as is", without charge, subject to all terms of use at http://www.image.ucar.edu/DAReS/DART/DART_download


{% extends "format.html" %} {% load static %} {% load filter %} {% block title %}StocksEra | FTD {% endblock %} {% block additional_script %} {% endblock %} {% block onload_properties%}display_data();ftd_graph(48);display_table();restore_dark_mode();{% endblock %} {% block main_nav %}
Failure to Deliver (FTD) data is retrieved from the US Securities and Exchange Commission (SEC). It occurs when a broker-dealer fails to deliver securities to the party on the other side of the transaction on the settlement date. What is T+35 Theory? It means to check for FTD surges (example: FTD Quantity more than 1 million/more than 90th percentile of FTD Amount and at least 100k FTD) for stocks that are heavily shorted such as AMC and GME and count 34 trading days after the surge date. On that date, stocks might experience a surge in price action. You can refer to this post on Reddit for more information.


FREETOWN, January 6 (Xinhua) -- Five government soldiers arrested by the Sierra Leone Naval Patrol Unit early November last year have been jailed for 10 years each with hard labor, Justice Ministry officials said today.
The soldiers who were sentenced to jail on Saturday had attacked a Spanish fishing boat offshore Freetown, capital of Sierra Leone, according to the officials.
"We are now determined to stamp out piracy and make the country's territorial waters safe," one official said.
According to the ministry's statistics, piratical attacks for the past three years on fishing boats plying the country's coastal waters have increased five fold to about an average of four a month, with the highest falling in the month of November last year.
Naval Commander Alimamy Sesay in an interview said, "stiffer penalties should be given to pirates as from now on."
Last September, Spanish and Canary Island boat owners protested to Sierra Leone over what they called "the high incidence of piracy and they threatened to withdraw their boats from Sierra Leone if the government does not step up the battle against piracy."


Seniors fees are £35 per calender month, payable by standing order.
If you are not already a member of the British Kendo Association then you will also need to register with them and get insured.
Annual membership of the BKA is £40
Saturdays 10am-12pm
Junior fees are £30 per calender month, payable by standing order.
If you are not already a member of the British Kendo Association then you will also need to register with them and get insured.
Annual membership of the BKA is £15
Ichi ByōShi offers kendo for children aged 8-17 that are keen to learn the sport. Like the adult class, this is hosted in Aylesbury High School.
The club offers a beginners package to allow members to try out Kendo and see if this is the martial art for them. The package has been designed to minimise cost to you, but also to ensure that your initial experience is sufficiently long and comprehensive enough to enable you to make a decision.
The package costs £30 and consists of the following:
If you would like to come and visit the club, you are welcome to come along and observe a training session. We apologise but we cannot allow you to train with us on that visit.
In order to train you MUST have insurance. Insurance is gained through membership of the British Kendo Association and is the only source we recognise.
If you are joining us from another club, then you will be required to prove membership.
New joiners who take the beginners package, will have 3 months of temporary membership, with insurance, from the BKA. At the end of the trial period, this will need to be converted to full membership.
Annual Seniors fee: £40
Annual Concession/student fee: £30
Annual Juniors fee: £25


Password Cracker
checkpwd
will crack the DES-based hashes from Oracle 8, 9 and 10.
Port 2100 - Oracle XML DB
Can be accessed through ftp.
Default logins:
sys:sys
scott:tiger


Custom Code
Introduction¶
What follows is a detailed tutorial that walks developers through the steps of writing custom code for an Android application using P2UX. Developers should be familiar with the Android Studio integrated development environment for MacOS and the Java programming languages for custom coding.
Topics include customizable View and control behaviors, Screen/Panels, and UI controls.
Terminology
Throughout the P2UX documentation the “developer” refers to you, the reader who is developing an app with P2UX. The “designer” refers to the individual whose principal job is to create the appearance and style of the app and its visual components. “PRL” refers to the P2UX Rendering Library for iOS, which controls the creation and workflow of content created for the P2UX platform.
Coding examples and code additions
In the coding examples below and throughout the documentation, changes and additions to be made by the developer are rendered with a blue highlight.
P2UX versus the standard Android Studio environment
P2UX based applications are easy to customize and extend for Android. The P2UX Android rendering library is based on the Android Widget package (android.widget) and other Android primitives. This means that writing custom business logic and integrating custom controls works much the same as it does when writing Android applications using Android Studio. With the P2UX platform, XML Layout files are no longer required for Android development. Instead, applications use P2UX Portable UX Bundles (PUB) either as embedded or dynamically accessed resources. Additionally, P2UX provides hooks to developers that allow them access to all of the components of P2UX as well as the ability to fully customize instances of the application.
Create a P2UX enabled project first
This document assumes a P2UX enabled Android Studio project has already been created. See Quick Start for steps to create a project.
P2UX and Android Studio¶
Java
P2UX native rendering libraries for Android can be extended using the Java programming language. The instructions below provide explicit reference to the proper use of Java coding in each applicable step that follows.
Adding Custom Behaviors¶
If desired, customizable behaviors can be added to the project code.
A subclass of the P2UXAppBehavior
class is the starting point for customizing the behavior of the application. From this class, all other parts of the application can be customized. (Common customized behaviors include creation of a Custom Control or overriding a particular View.)
In Android Studio, create a class to store the customized behaviors. The easiest way to do is by doing a right click on your project package and selecting New->Java Class. (This example uses the name SampleBehavior
.) In the Create New Class dialog, type in P2UXAppBehavior in the Superclass field.
This will create SampleBehavior
class. Put any customized behaviors within the implementation here. Below is a list of available customization methods for P2UXAppBehavior
:
| Modifier and Type | Method and Description |
|---|---|
| P2UXFragment | createViewFragment(int type, Context context, P2UXDefinition def, P2UXFragment.UXFragmentDelegate fragmentDelegate, RectF rect, boolean cache, Object index, Object data, P2UXViewContainerDelegate viewDelegate) Creates a custom fragment |
| P2UXScreen | createScreen(Context context, P2UXDefinition def, RectF rect, Object index, Object data, P2UXViewContainerDelegate viewDelegate) Creates a custom screen |
| P2UXPanel | createPanel(Context context, P2UXDefinition def, RectF rect, Object index, Object data, P2UXViewContainerDelegate viewDelegate) Creates a custom panel |
| View | createControl(String type, P2UXElementInstance elInstance, RectF rect, P2UXViewContainerDelegate viewDelegate, Object index, Object data) Creates a custom control |
In addition, update MainActivity
to include the custom behaviors.
To do this,MainActivity
must override the method createBehavior
. (This will override any default behaviors.) Edit MainActivity
to look like this:
@Override public void onCreate(Bundle savedInstanceState) { mAppKey = "xxxxx"; try { mResources = new JSONArray(); JSONObject resource = new JSONObject(); resource.put(P2UXAppTypes.P2UXApp_PackageAttrib_FormFactor, 0); resource.put(P2UXAppTypes.P2UXApp_PackageAttrib_Type, P2UXAppTypes.P2UXApp_PackageType_Static); resource.put(P2UXAppTypes.P2UXApp_PackageAttrib_Package, "shellui_phone"); resource.put(P2UXAppTypes.P2UXApp_PackageAttrib_Update, P2UXAppTypes.P2UXApp_PackageUpdate_None); mResources.put(resource); } catch (JSONException e) { P2UXLog.e(TAG, "onCreate - " + e.getMessage()); } if ((getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) == ApplicationInfo.FLAG_DEBUGGABLE) { if (savedInstanceState == null) { savedInstanceState = new Bundle(); } savedInstanceState.putString(P2UXAppCreator.P2UXAppCreator_Opt_Env, P2UXAppCreator.P2UXAppCreator_Opt_Env_Prototype); savedInstanceState.putLong(P2UXAppCreator.P2UXAppCreator_Opt_LogLevel, P2UXLog.P2UXCoreLogFlagVerbose); } super.onCreate(savedInstanceState); applyTranslucentStatusBar(); } @Override public P2UXAppBehavior createBehavior(String appId) { return new SampleAppBehavior(); }
Adding Custom Fragment¶
Developers can override Fragment instances to provide any custom code needed for a fragment lifecycle/behavior and its hosted View
.
The PRL will request an instance from P2UXAppBehavior
when it needs to create a new fragment. If no instance is provided, P2UX will generate a standard instance of the Fragment.
To provide a custom Fragment instance, override the method createViewFragment
from a P2UXAppBehavior
subclass and return an instance of P2UXFragment
.
To handle button click action, override the method handleButtonClick
from P2UXAppFragment
. To access a control in the fragment, override the method viewCreated
from P2UXAppFragment
.
The name of a chosen Fragment is the value used to identify the screen when the PRL creates an instance of this object. The “def” parameter passed to this method contains the member variable systemType
that identifies the Screen being created. From this object, the developer determines the requested Screen and the specific P2UXFragment
subclass to instantiate.
Creating a custom Fragment instance in a P2UXAppBehavior
subclass
@Override public P2UXFragment createViewFragment(int type, Context context, P2UXDefinition def, P2UXFragment.UXFragmentDelegate fragmentDelegate, RectF rect, boolean cache, Object index, Object data, P2UXViewContainerDelegate viewDelegate) { if (def.getSystemType().equals("xxxxx")) { //return a fragment here, for example: return new SampleFragment(context, def, fragmentDelegate, rect, cache, index, data, viewDelegate); } return super.createViewFragment(type, context, def, fragmentDelegate, rect, cache, index, data, viewDelegate); } @Override public void viewCreated() { super.viewCreated(); P2UXButton btn = (P2UXButton) controlWithElementSystemTypeOrId("show_btn"); if (btn != null) { btn.setEnabled(false); } } @Override public boolean handleButtonClick(View ctrl) { P2UXElementInstance elementInstance = P2UXControlHelper.getElementInstance(ctrl); if (elInstance != null && elInstance.getSystemType.equals("button1")) { String elId = elInstance.getElId(); if (elId != null && elId.equals("button1")) { // take some custom action here for the "okbtn" // return true to indicate the event was handled and propagation // shouldn't continue return true; } } return super.handleButtonClick(ctrl); }
Adding Custom Screens/Panels¶
Developers can override Screen or Panel instances to provide any custom code needed for a hosted View
.
Since the P2UX UI is not based on XML Layout, connecting custom methods for each button click action is unnecessary. Instead, the developer can override the methods of the P2UXScreen
class to handle button click and other UI events. (In all other respects, writing code for customized Screen and Panel behavior is the same as for XML layout-based content.)
The PRL will request an instance from P2UXAppBehavior
when it needs to create a new Screen or Panel. If no instance is provided, P2UX will generate a standard instance of the Screen or Panel.
To provide a custom Screen instance, override the method createScreen
from a P2UXAppBehavior
subclass and return an instance of P2UXScreen
. To provide a custom Panel instance, override the method createPanel
and return an instance of P2UXPanel
. (Both P2UXScreen
and P2UXPanel
are View
based subclasses that add some additional helper methods. These methods make it easier to access screen components.)
The name of a chosen Screen or Panel is the value used to identify the item when the PRL creates an instance of this object. The “def” parameter passed to this method contains the member variable systemType
that identifies the Screen being created. From this object, the developer determines the requested Screen and the specific P2UXScreen
or P2UXPanel
subclass to instantiate.
Creating a custom Screen or Panel instance in a P2UXAppBehavior
subclass
@Override public P2UXScreen createScreen(Context context, P2UXDefinition def, RectF rect, Object index, Object data, P2UXViewContainerDelegate viewDelegate) { if (def.getSystemType().equals("xxxxx")) { //return some screen here, for example: return new SampleScreen(context, rect, def, viewDelegate, index, data); } return super.createScreen(context, def, rect, index, data, viewDelegate); } @Override public P2UXPanel createPanel(Context context, P2UXDefinition def, RectF rect, Object index, Object data, P2UXViewContainerDelegate viewDelegate) { if (def.getSystemType().equals("xxxxx")) { //return some screen here, for example: return new SamplePanel(context, rect, def, viewDelegate, index, data); } return super.createPanel(context, def, rect, index, data, viewDelegate); }
Accessing Control instances from P2UXPanel
or P2UXScreen
¶
To access instances of controls, P2UXScreen
provides a helper method, controlWithElementSystemTypeOrId
. This method takes the name or id of the control to be accessed and returns a control instance.
“System type” references
After creating a control, the developer can set a “system type” for the control in Builder. This effectively becomes the name for the new control. Referring to the control by its “system type” means that the developer does not need to change any existing custom code when choosing to create an alternate variation of the same control. (Otherwise, if the developer changes the name of the control in Builder, any custom code to referring to the new name would have to be changed as well.)
Accessing a control in a custom instance of P2UXScreen
looks like this:
@Override public void showView(boolean reload) { super.showView(reload); P2UXButton btn = (P2UXButton) controlWithElementSystemTypeOrId("show_btn"); if (btn != null) { btn.setEnabled(false); } }
Handling Events from P2UXAppController¶
End-users of a completed app will interact with controls in a Screen or Panel to generate events. These interactions will, in turn, trigger actions. Typically the PRL handles events directly through event interactions set up in Builder. In some cases, additional custom code may be needed to trigger actions not directly supported by P2UX.
The PRL provides a chain of event handlers that propagate an event through different components. Handling events at any point in the propagation chain provides a way to trigger custom code and also (optionally) to stop the propagation of the event at any specific handler.
Event propagation follows a set pattern.
First, events are relayed to the P2UXScreen
for the current Screen or Panel. Next, they pass to P2UXAppBehavior
. Finally, events are handled by the custom instance of the View
itself. If none of these components halt event propagation, the PRL will then handle any interactions defined for the event in Builder.
The P2UXScreen
contains helper methods that handle a variety of events when they occur. These methods give the developer a chance to integrate any custom code needed from the basic event level without triggering any custom actions.
Most standard control events are routed through the P2UXScreen
instance. Handling these events is a matter of overriding the appropriate event method in your P2UXScreen subclass. Event propagation can be allowed to continue or not depending on the return value from the event handler methods.
The example below illustrates the code that handles a Button press event.
Handling a Button press event in P2UXScreen subclass:
@Override public boolean handleButtonClick(View ctrl, P2UXElementInstance elInstance) { if (elInstance != null && elInstance.getSystemType.equals("button1")) { String elId = elInstance.getElId(); if (elId != null && elId.equals("button1")) { // take some custom action here for the "okbtn" // return true to indicate the event was handled and propagation // shouldn't continue return true; } } return super.handleButtonClick(ctrl); }
Adding Custom UI Controls¶
UI Controls are the visual components of a Screen or Panel created in the Builder tool. These can be interactive, like Buttons or Sliders, or non-interactive, like Shapes or Text. Although P2UX offers many different UI Controls directly creatable and usable in Builder, a specific application may require developer-defined UI controls. Builder provides a Custom Control component that can be added to a Screen or Panel and then replaced using custom code.
Any View
based control can be injected into your Screens and Panels via a Custom Control. This allows for existing custom controls or third party custom controls to be used with P2UX based applications.
The PRL manages the size and position of any custom controls defined using Builder. To provide an instance of a custom control, override the method createControl in your P2UXAppBehavior
subclass and return the View
subclassed instance of your control. The first parameter passed to this method, type, is the name of the control set when you created the custom control in Builder. P2UX will pass the initial size to use with your Custom Control, as well as a few other components that can be used to access any custom information created with your control in Builder.
The elementInstance parameter contains all the parameters specified using Builder for the control via its itemSpec member.
Create a custom control in P2UXAppBehavior
subclass like this:
@Override public View createControl(String type, P2UXElementInstance elemInstance, RectF rect, P2UXViewContainerDelegate viewDelegate, Object index, Object data) { if (type != null && !type.isEmpty()) { if (type.equals("calendar")) { // Below is an example of implementing a calendar using CalendarView View ctrl = new CalendarView(mContext); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int)rect.width(), (int)rect.height()); params.leftMargin = (int)rect.left; params.topMargin = (int)rect.top; ctrl.setLayoutParams(params); ((CalendarView) ctrl).setOnDateChangeListener(new CalendarView.OnDateChangeListener() { @Override public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) { Toast.makeText(mContext, month+1 + "/" + dayOfMonth + "/" + year, Toast.LENGTH_SHORT).show(); } }); return ctrl; } } return super.createControl(type, elemInstance, rect, viewDelegate, index, data); }


3
Steven
- Ball
8.1.a navindex and accesskey (non-normative)
This test case is non-normative and assumes that navindex attributes
will be recognized and interpreted as described in section 4.3.1 of the specification.
Navigation order must be the Name input first, the Item input second, and the Quantity input third.
Keyboard users can use the Tab key to test the navigation order.
The input controls are also set to use access keys. Keyboard users can hold down the Alt key, the Shift
key, and the key in parentheses in the labels of the input controls to jump directly to an input control.
Quantity(q):
Name(n):
Item(i):


In the Construction Room put together the Cubees to make a model.
In the Scene Room put together models to make a scene.
When in the Scene Room you can view the scene by a flythrough.
This Workshop is a basic introduction to building with Just Cubees.
With Just Cubees you cannot change the size of a Cubee nor make your own Cubees.


--- layout: default ---
If this is your first race, you can check your category, which will take your Zwift ID and check your race history. Your category will not always align with ZwiftPower, so please use the tool.
If you have already completed a race in the current series, then you need to race in the category you finished in on ZwiftPower for your last race. You may choose to race in a higher category if you prefer, but you will not be able to race down a grade in later races. It is preferable to check results a day before entering, as results may not have been finalised. You can check the Wild Women Facebook Page for news on race results.
If you end up being upgraded in a race, you will score points in the upgraded category. 50% of points you have accumulated prior will be carried over.
However, you must start the race in the correct category to score points. Currently, there is an issue with the scoring system where this isn’t yet taken into account, so please race fair by using the correct category.
For non-TT races, you can use any bike except for TT bikes. For TT races, you will need to select a TT frame. Whilst you can race without a TT frame, you will not be able to draft off other riders. Given that TT frames will generally be the fastest options available, it is recommended to choose one. You can learn more about TT bikes at Zwift Insider.
Women found using a shared account will be disqualified, as we cannot verify which category you should be racing in.
Women using zPower for racing or women without a heart rate monitor will be ineligible for podiums, and will receive a time penalty to place them lower in results.
If you switch teams mid-league, points accrued for your previous team will remain with that team. Points accrued whilst racing with your new team will go to that team for the remaining races.
Please use Facebook’s messaging feature on our Facebook Page.
Yes you can! For individual points, we will take your best point scoring finish of the two races. For teams points, we will add both results to the team total.
Yes! Our partners at Primal Europe are giving away £10 for one lucky winner in each grade. You must complete four rounds to be eligible to win. Winners will be drawn at random from each grade.


gitGraph class BankAccount{ +String owner +BigDecimal balance +deposit(amount) bool +withdrawl(amount) int } cssClass "BankAccount" customCss


Customers will never love a company until the employees love it first.
We aim to provide life changing business consultation to our customers and the tools to achieve their business goals. While doing so, we want to be the most sought out business consultants in the technology area.
Leads the technology and product divisions
Customer evangelist
Another team member!
Another team member!
Another team member!
Another team member!


Since i use xbox i never use to battlelog friends. I cant remove it, it would be nice to see something there. Ive seen other 3th party web sites and plugins do it, so why not battlelog.
ORFK
Global Moderator
1.) we cant do a function, which will remove your friends.
2.) this is already included in battlelog, you just have to open your eyes. Try it on the profile page of your friend or in your own profile page -> friend-list, somewhere you will find an X.
3.) they are not Battlelog friends, they are origin friends, so you can remove them in Origin too.


{% extends 'layout-newia.html' %} {% block pageTitle %} Mental Health {% endblock %} {% block beforeContent %} {% endblock %} {% block content %}
Most people feel anxious or scared sometimes, but if it's affecting your life there are things you can try that may help.
Support is also available if you're finding it hard to cope with anxiety, fear or panic.
Anxiety can cause many different symptoms. It might affect how you feel physically, mentally and how you behave.
It's not always easy to recognise when anxiety is the reason you're feeling or acting differently.
If you experience sudden, intense anxiety and fear, it might be the symptoms of a panic attack. Other symptoms may include:
A panic attack usually lasts 5 to 30 minutes. They can be very frightening, but they're not dangerous and should not harm you.
If you're not sure how you feel, try our mood self-assessment.
try talking about your feelings to a friend, family member, health professional or counsellor. You could also contact Samaritans, call: 116 123 or email<EMAIL_ADDRESS>if you need someone to talk to
exercise – activities such as running, walking, swimming and yoga can help you relax
find out how to get to sleep if you're struggling to sleep
eat a healthy diet with regular meals to keep your energy levels stable
consider peer support, where people use their experiences to help each other. Find out more about peer support on the Mind website
listen to free mental wellbeing audio guides
search and download relaxation and mindfulness apps or online community apps from the NHS apps library
do not try to do everything at once – set small targets that you can easily achieve
do not focus on the things you cannot change – focus your time and energy into helping yourself feel better
do not avoid situations that make you anxious – try slowly building up time spent in worrying situations to gradually reduce anxiety
try not to tell yourself that you're alone; most people experience anxiety or fear at some point in their life
try not to use alcohol, cigarettes, gambling or drugs to relieve anxiety as these can all contribute to poor mental health
The mental health charity Mind offers more information on:
Your Mind Plan on the Every Mind Matters website sends personalised tips and advice to your email inbox.
If you need more support, you can get free psychological therapies such as cognitive behavioural therapy (CBT) on the NHS.
You can refer yourself directly to a psychological therapies service without a referral from a GP.
It's still important to get help from a GP if you need it. To contact your GP surgery:
111 can tell you the right place to get help if you need to see someone.
There are many different causes of anxiety, fear or panic and it's different for everyone.
When you're feeling anxious or scared, your body releases stress hormones, such as adrenaline and cortisol.
This can be helpful in some situations, but it might also cause physical symptoms such as an increased heart rate and increased sweating. In some people, it might cause a panic attack.
Regular anxiety, fear or panic can also be the main symptom of several health conditions. Do not self-diagnose – speak to a GP if you're worried about how you're feeling.
If you know what's causing anxiety, fear or panic, it might be easier to find ways to manage it.
Some examples of possible causes include:
Even significant life events such as buying a house, having a baby or planning a wedding could lead to feelings of stress and anxiety.
You might find it hard to explain to people why you feel this way, but talking to someone could help you find a solution.
Find out more about the 5 steps to mental wellbeing.


Model1 Output is ==>
Name1 is "${this.value}" :
Name2 is "${this.value}" :
Name3 is "${this.value}"
Model2 Output is ==>
Name1 is "${this.value}" :
Name2 is "${this.value}"
Model3 Output is ==>
Name1 is "${this.value}"


Source: https://github.com/SEscobedo/AstraSolaris/blob/dev/.github/CONTRIBUTING.md
It is assumed that you know a little about node.js, git and threejs. If not, here's some help to get started with git and here’s some help to get started with node.js. For threejs you can visit threejs.org.
As per the npm standard, ‘start’ is the place to begin the package.
$ npm start
This script will start a local server similar to astrasolaris.org, but instead will be hosted on your local machine. Browse to http://localhost:5000/ to check it out.
If you’d like to make a minified version of the build files i.e. build/astra.js run:
$ npm run build
Build files are generated from src directory.
When you’ve decided to make changes, start with the following:
$ git pull https://github.com/SEscobedo/AstraSolaris.git
$ git push
$ git checkout dev
$ git branch [mychangesbranch]
$ git checkout [mychangesbranch]
This project is currently contributed to mostly via everyone's spare time. Please keep that in mind as it may take some time for the appropriate feedback to get to you. If you are unsure about adding a new feature, it might be better to ask first to see whether other people think it's a good idea. You can do this at github discussions https://github.com/SEscobedo/AstraSolaris/discussions.


PERLBOT
Section: Perl Programmers Reference Guide (1)Updated: 2009-02-12
Index Return to Main Contents
NAME
perlbot - Bag'o Object Tricks (the BOT)DESCRIPTION
The following collection of tricks and hints is intended to whet curious appetites about such things as the use of instance variables and the mechanics of object and class relationships. The reader is encouraged to consult relevant textbooks for discussion of Object Oriented definitions and methodology. This is not intended as a tutorial for object-oriented programming or as a comprehensive guide to Perl's object oriented features, nor should it be construed as a style guide. If you're looking for tutorials, be sure to read perlboot, perltoot, and perltooc.The Perl motto still holds: There's more than one way to do it.
OO SCALING TIPS
- 1.
- Do not attempt to verify the type of $self. That'll break if the class is inherited, when the type of $self is valid but its package isn't what you expect. See rule 5.
- 2.
- If an object-oriented (OO) or indirect-object (IO) syntax was used, then the object is probably the correct type and there's no need to become paranoid about it. Perl isn't a paranoid language anyway. If people subvert the OO or IO syntax then they probably know what they're doing and you should let them do it. See rule 1.
- 3.
- Use the two-argument form of bless(). Let a subclass use your constructor. See ``INHERITING A CONSTRUCTOR''.
- 4.
- The subclass is allowed to know things about its immediate superclass, the superclass is allowed to know nothing about a subclass.
- 5.
- Don't be trigger happy with inheritance. A ``using'', ``containing'', or ``delegation'' relationship (some sort of aggregation, at least) is often more appropriate. See ``OBJECT RELATIONSHIPS'', ``USING RELATIONSHIP WITH SDBM'', and ``DELEGATION''.
- 6.
- The object is the namespace. Make package globals accessible via the object. This will remove the guess work about the symbol's home package. See ``CLASS CONTEXT AND THE OBJECT''.
- 7.
- IO syntax is certainly less noisy, but it is also prone to ambiguities that can cause difficult-to-find bugs. Allow people to use the sure-thing OO syntax, even if you don't like it.
- 8.
- Do not use function-call syntax on a method. You're going to be bitten someday. Someone might move that method into a superclass and your code will be broken. On top of that you're feeding the paranoia in rule 2.
- 9.
- Don't assume you know the home package of a method. You're making it difficult for someone to override that method. See ``THINKING OF CODE REUSE''.
INSTANCE VARIABLES
An anonymous array or anonymous hash can be used to hold instance variables. Named parameters are also demonstrated.
package Foo; sub new { my $type = shift; my %params = @_; my $self = {}; $self->{'High'} = $params{'High'}; $self->{'Low'} = $params{'Low'}; bless $self, $type; } package Bar; sub new { my $type = shift; my %params = @_; my $self = []; $self->[0] = $params{'Left'}; $self->[1] = $params{'Right'}; bless $self, $type; } package main; $a = Foo->new( 'High' => 42, 'Low' => 11 ); print "High=$a->{'High'}\n"; print "Low=$a->{'Low'}\n"; $b = Bar->new( 'Left' => 78, 'Right' => 40 ); print "Left=$b->[0]\n"; print "Right=$b->[1]\n";
SCALAR INSTANCE VARIABLES
An anonymous scalar can be used when only one instance variable is needed.
package Foo; sub new { my $type = shift; my $self; $self = shift; bless \$self, $type; } package main; $a = Foo->new( 42 ); print "a=$$a\n";
INSTANCE VARIABLE INHERITANCE
This example demonstrates how one might inherit instance variables from a superclass for inclusion in the new class. This requires calling the superclass's constructor and adding one's own instance variables to the new object.
package Bar; sub new { my $type = shift; my $self = {}; $self->{'buz'} = 42; bless $self, $type; } package Foo; @ISA = qw( Bar ); sub new { my $type = shift; my $self = Bar->new; $self->{'biz'} = 11; bless $self, $type; } package main; $a = Foo->new; print "buz = ", $a->{'buz'}, "\n"; print "biz = ", $a->{'biz'}, "\n";
OBJECT RELATIONSHIPS
The following demonstrates how one might implement ``containing'' and ``using'' relationships between objects.
package Bar; sub new { my $type = shift; my $self = {}; $self->{'buz'} = 42; bless $self, $type; } package Foo; sub new { my $type = shift; my $self = {}; $self->{'Bar'} = Bar->new; $self->{'biz'} = 11; bless $self, $type; } package main; $a = Foo->new; print "buz = ", $a->{'Bar'}->{'buz'}, "\n"; print "biz = ", $a->{'biz'}, "\n";
OVERRIDING SUPERCLASS METHODS
The following example demonstrates how to override a superclass method and then call the overridden method. The SUPER pseudo-class allows the programmer to call an overridden superclass method without actually knowing where that method is defined.
package Buz; sub goo { print "here's the goo\n" } package Bar; @ISA = qw( Buz ); sub google { print "google here\n" } package Baz; sub mumble { print "mumbling\n" } package Foo; @ISA = qw( Bar Baz ); sub new { my $type = shift; bless [], $type; } sub grr { print "grumble\n" } sub goo { my $self = shift; $self->SUPER::goo(); } sub mumble { my $self = shift; $self->SUPER::mumble(); } sub google { my $self = shift; $self->SUPER::google(); } package main; $foo = Foo->new; $foo->mumble; $foo->grr; $foo->goo; $foo->google;
Note that "SUPER" refers to the superclasses of the current package ("Foo"), not to the superclasses of $self.
USING RELATIONSHIP WITH SDBM
This example demonstrates an interface for the SDBM class. This creates a ``using'' relationship between the SDBM class and the new class Mydbm.
package Mydbm; require SDBM_File; require Tie::Hash; @ISA = qw( Tie::Hash ); sub TIEHASH { my $type = shift; my $ref = SDBM_File->new(@_); bless {'dbm' => $ref}, $type; } sub FETCH { my $self = shift; my $ref = $self->{'dbm'}; $ref->FETCH(@_); } sub STORE { my $self = shift; if (defined $_[0]){ my $ref = $self->{'dbm'}; $ref->STORE(@_); } else { die "Cannot STORE an undefined key in Mydbm\n"; } } package main; use Fcntl qw( O_RDWR O_CREAT ); tie %foo, "Mydbm", "Sdbm", O_RDWR|O_CREAT, 0640; $foo{'bar'} = 123; print "foo-bar = $foo{'bar'}\n"; tie %bar, "Mydbm", "Sdbm2", O_RDWR|O_CREAT, 0640; $bar{'Cathy'} = 456; print "bar-Cathy = $bar{'Cathy'}\n";
THINKING OF CODE REUSE
One strength of Object-Oriented languages is the ease with which old code can use new code. The following examples will demonstrate first how one can hinder code reuse and then how one can promote code reuse.This first example illustrates a class which uses a fully-qualified method call to access the ``private'' method BAZ(). The second example will show that it is impossible to override the BAZ() method.
package FOO; sub new { my $type = shift; bless {}, $type; } sub bar { my $self = shift; $self->FOO::private::BAZ; } package FOO::private; sub BAZ { print "in BAZ\n"; } package main; $a = FOO->new; $a->bar;
Now we try to override the BAZ() method. We would like FOO::bar() to call GOOP::BAZ(), but this cannot happen because FOO::bar() explicitly calls FOO::private::BAZ().
package FOO; sub new { my $type = shift; bless {}, $type; } sub bar { my $self = shift; $self->FOO::private::BAZ; } package FOO::private; sub BAZ { print "in BAZ\n"; } package GOOP; @ISA = qw( FOO ); sub new { my $type = shift; bless {}, $type; } sub BAZ { print "in GOOP::BAZ\n"; } package main; $a = GOOP->new; $a->bar;
To create reusable code we must modify class FOO, flattening class FOO::private. The next example shows a reusable class FOO which allows the method GOOP::BAZ() to be used in place of FOO::BAZ().
package FOO; sub new { my $type = shift; bless {}, $type; } sub bar { my $self = shift; $self->BAZ; } sub BAZ { print "in BAZ\n"; } package GOOP; @ISA = qw( FOO ); sub new { my $type = shift; bless {}, $type; } sub BAZ { print "in GOOP::BAZ\n"; } package main; $a = GOOP->new; $a->bar;
CLASS CONTEXT AND THE OBJECT
Use the object to solve package and class context problems. Everything a method needs should be available via the object or should be passed as a parameter to the method.A class will sometimes have static or global data to be used by the methods. A subclass may want to override that data and replace it with new data. When this happens the superclass may not know how to find the new copy of the data.
This problem can be solved by using the object to define the context of the method. Let the method look in the object for a reference to the data. The alternative is to force the method to go hunting for the data (``Is it in my class, or in a subclass? Which subclass?''), and this can be inconvenient and will lead to hackery. It is better just to let the object tell the method where that data is located.
package Bar; %fizzle = ( 'Password' => 'XYZZY' ); sub new { my $type = shift; my $self = {}; $self->{'fizzle'} = \%fizzle; bless $self, $type; } sub enter { my $self = shift; # Don't try to guess if we should use %Bar::fizzle # or %Foo::fizzle. The object already knows which # we should use, so just ask it. # my $fizzle = $self->{'fizzle'}; print "The word is ", $fizzle->{'Password'}, "\n"; } package Foo; @ISA = qw( Bar ); %fizzle = ( 'Password' => 'Rumple' ); sub new { my $type = shift; my $self = Bar->new; $self->{'fizzle'} = \%fizzle; bless $self, $type; } package main; $a = Bar->new; $b = Foo->new; $a->enter; $b->enter;
INHERITING A CONSTRUCTOR
An inheritable constructor should use the second form of bless() which allows blessing directly into a specified class. Notice in this example that the object will be a BAR not a FOO, even though the constructor is in class FOO.
package FOO; sub new { my $type = shift; my $self = {}; bless $self, $type; } sub baz { print "in FOO::baz()\n"; } package BAR; @ISA = qw(FOO); sub baz { print "in BAR::baz()\n"; } package main; $a = BAR->new; $a->baz;
DELEGATION
Some classes, such as SDBM_File, cannot be effectively subclassed because they create foreign objects. Such a class can be extended with some sort of aggregation technique such as the ``using'' relationship mentioned earlier or by delegation.The following example demonstrates delegation using an AUTOLOAD() function to perform message-forwarding. This will allow the Mydbm object to behave exactly like an SDBM_File object. The Mydbm class could now extend the behavior by adding custom FETCH() and STORE() methods, if this is desired.
package Mydbm; require SDBM_File; require Tie::Hash; @ISA = qw(Tie::Hash); sub TIEHASH { my $type = shift; my $ref = SDBM_File->new(@_); bless {'delegate' => $ref}; } sub AUTOLOAD { my $self = shift; # The Perl interpreter places the name of the # message in a variable called $AUTOLOAD. # DESTROY messages should never be propagated. return if $AUTOLOAD =~ /::DESTROY$/; # Remove the package name. $AUTOLOAD =~ s/^Mydbm:://; # Pass the message to the delegate. $self->{'delegate'}->$AUTOLOAD(@_); } package main; use Fcntl qw( O_RDWR O_CREAT ); tie %foo, "Mydbm", "adbm", O_RDWR|O_CREAT, 0640; $foo{'bar'} = 123; print "foo-bar = $foo{'bar'}\n";
SEE ALSO
perlboot, perltoot, perltooc.
Index
- NAME
- DESCRIPTION
- OO SCALING TIPS
- INSTANCE VARIABLES
- SCALAR INSTANCE VARIABLES
- INSTANCE VARIABLE INHERITANCE
- OBJECT RELATIONSHIPS
- OVERRIDING SUPERCLASS METHODS
- USING RELATIONSHIP WITH SDBM
- THINKING OF CODE REUSE
- CLASS CONTEXT AND THE OBJECT
- INHERITING A CONSTRUCTOR
- DELEGATION
- SEE ALSO
This document was created by man2html, using the manual pages.
Time: 05:29:07 GMT, December 24, 2015


|
JavaTM 2 Platform Standard Ed. 5.0 |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface ServerRequestInterceptorOperations
Server-side request interceptor.
A request Interceptor is designed to intercept the flow of a request/reply sequence through the ORB at specific points so that services can query the request information and manipulate the service contexts which are propagated between clients and servers. The primary use of request Interceptors is to enable ORB services to transfer context information between clients and servers. There are two types of request Interceptors: client-side and server-side.
To write a server-side Interceptor, implement the ServerRequestInterceptor interface.
ServerRequestInfo
| Method Summary | |
|---|---|
void |
receive_request_service_contexts(ServerRequestInfo ri)
Allows the interceptor to process service context information. |
void |
receive_request(ServerRequestInfo ri)
Allows an Interceptor to query request information after all the information, including operation parameters, are available. |
void |
send_exception(ServerRequestInfo ri)
Allows an Interceptor to query the exception information and modify the reply service context before the exception is thrown to the client. |
void |
send_other(ServerRequestInfo ri)
Allows an Interceptor to query the information available when a request results in something other than a normal reply or an exception. |
void |
send_reply(ServerRequestInfo ri)
Allows an Interceptor to query reply information and modify the reply service context after the target operation has been invoked and before the reply is returned to the client. |
| Methods inherited from interface org.omg.PortableInterceptor.InterceptorOperations |
|---|
destroy, name |
| Method Detail |
|---|
void receive_request_service_contexts(ServerRequestInfo ri) throws ForwardRequest
At this interception point, Interceptors must get their service
context information from the incoming request transfer it to
PortableInterceptor.Current
's slots.
This interception point is called before the servant manager is called. Operation parameters are not yet available at this point. This interception point may or may not execute in the same thread as the target invocation.
This interception point may throw a system exception. If it does,
no other Interceptors' receive_request_service_contexts
operations are called. Those Interceptors on the Flow Stack are
popped and their send_exception
interception points are
called.
This interception point may also throw a ForwardRequest
exception. If an Interceptor throws this exception, no other
Interceptors' receive_request_service_contexts
operations
are called. Those Interceptors on the Flow Stack are popped and
their send_other
interception points are called.
Compliant Interceptors shall properly follow
completion_status
semantics if they throw a system
exception from this interception point. The
completion_status
shall be COMPLETED_NO.
ri
- Information about the current request being intercepted.
ForwardRequest
- If thrown, indicates to the ORB that a
retry of the request should occur with the new object given in
the exception.void receive_request(ServerRequestInfo ri) throws ForwardRequest
In the DSI model, since the parameters are first available when
the user code calls arguments
, receive_request
is called from within arguments
. It is possible that
arguments
is not called in the DSI model. The target
may call set_exception
before calling
arguments
. The ORB shall guarantee that
receive_request
is called once, either through
arguments
or through set_exception
. If it
is called through set_exception
, requesting the
arguments will result in NO_RESOURCES
being thrown with
a standard minor code of 1.
This interception point may throw a system exception. If it does, no
other Interceptors' receive_request
operations are
called. Those Interceptors on the Flow Stack are popped and their
send_exception
interception points are called.
This interception point may also throw a ForwardRequest
exception. If an Interceptor throws this exception, no other
Interceptors' receive_request
operations are called.
Those Interceptors on the Flow Stack are popped and their
send_other
interception points are called.
Compliant Interceptors shall properly follow
completion_status
semantics if they throw a system
exception from this interception point. The
completion_status
shall be COMPLETED_NO
.
ri
- Information about the current request being intercepted.
ForwardRequest
- If thrown, indicates to the ORB that a
retry of the request should occur with the new object given in
the exception.void send_reply(ServerRequestInfo ri)
This interception point may throw a system exception. If it does,
no other Interceptors' send_reply
operations are called.
The remaining Interceptors in the Flow Stack shall have their
send_exception
interception point called.
Compliant Interceptors shall properly follow
completion_status
semantics if they throw a
system exception from this interception point. The
completion_status
shall be COMPLETED_YES
.
ri
- Information about the current request being intercepted.void send_exception(ServerRequestInfo ri) throws ForwardRequest
This interception point may throw a system exception. This has the
effect of changing the exception which successive Interceptors
popped from the Flow Stack receive on their calls to
send_exception
. The exception thrown to the client will
be the last exception thrown by an Interceptor, or the original
exception if no Interceptor changes the exception.
This interception point may also throw a ForwardRequest
exception. If an Interceptor throws this exception, no other
Interceptors' send_exception
operations are called. The
remaining Interceptors in the Flow Stack shall have their
send_other
interception points called.
If the completion_status
of the exception is not
COMPLETED_NO
, then it is inappropriate for this
interception point to throw a ForwardRequest
exception.
The request's at-most-once semantics would be lost.
Compliant Interceptors shall properly follow
completion_status
semantics if they throw a system
exception from this interception point. If the original exception
is a system exception, the completion_status
of the new
exception shall be the same as on the original. If the original
exception is a user exception, then the completion_status
of the new exception shall be COMPLETED_YES
.
ri
- Information about the current request being intercepted.
ForwardRequest
- If thrown, indicates to the ORB that a
retry of the request should occur with the new object given in
the exception.void send_other(ServerRequestInfo ri) throws ForwardRequest
LOCATION_FORWARD
status was
received). This interception point shall execute in the same thread
as the target invocation.
This interception point may throw a system exception. If it does,
no other Interceptors' send_other
operations are called.
The remaining Interceptors in the Flow Stack shall have their
send_exception
interception points called.
This interception point may also throw a ForwardRequest
exception. If an Interceptor throws this exception, successive
Interceptors' send_other
operations are called with
the new information provided by the ForwardRequest
exception.
Compliant Interceptors shall properly follow
completion_status
semantics if they throw a system
exception from this interception point. The
completion_status
shall be COMPLETED_NO
.
ri
- Information about the current request being intercepted.
ForwardRequest
- If thrown, indicates to the ORB that a
retry of the request should occur with the new object given in
the exception.
|
JavaTM 2 Platform Standard Ed. 5.0 |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Copyright © 2004, 2010 Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.