text:
<TITLE>Introduction to FAN Language and Utilities </TITLE>    <link rel="shortcut icon" href="http://www.unidata.ucar.edu/favicon.ico" type="image/x-icon" />

Introduction to FAN Language and Utilities

  FAN Version 2.0

Harvey Davies

  CSIRO Division of Atmospheric Research,

  Private Bag No. 1, Mordialloc 3195, Australia

  email: hld@dar.csiro.au

  Scientific Visitor from January to August 1996 at

  UCAR/Unidata Program Center,

  P.O. Box 3000, Boulder, Colorado 80307-3000, USA

  email: hld@ucar.edu

Introduction

FAN (File Array Notation) is an array-oriented language for identifying
  data items in files for the purpose of extraction or modification. FAN specifications
  consist of

one or more filenames

one or more variable (array) names or ID numbers

attribute names or ID numbers (optional)

dimension names or ID numbers (optional)

subscripts in various possible forms (optional)

NetCDF is the only format currently supported. However FAN is intended to be
  generic and it is hoped that there will eventually also be FAN interfaces to
  various other formats.

This document describes the FAN language and four utilities based on FAN. The
  use of these utilities can greatly decrease the need for programming in Fortran
  or C. They can be called from the Unix command line and shell scripts.

The first is <tt>nc2text</tt> which prints selected data from netCDF
  variables. The standard utility <tt>ncdump</tt> can also print data from
  netCDF variables, but only entire variables and only together with metadata
  in CDL form.

The second is <tt>ncmeta</tt> which prints selected metadata from one
  or more netCDF files. This metadata can include rank, shape, file names, variable
  names, dimension names and attribute names.

The third is <tt>ncrob</tt> which reads data from one or more netCDF
  variables, performs some process on it and then either prints the result or
  writes it to a netCDF array. The letters `<tt><b>rob</b></tt>' in `<tt>ncrob</tt>'
  stand for Reduce Or Broadcast. Reduce means to produce an
  array (e.g. sum, mean, maximum) with less dimensions than the original. Broadcast
  means to copy one array to another, recycling values if necessary. An example
  is copying the same vector to each row of a matrix. It is possible to process
  large volumes of data (e.g. 100 MB) using <tt>ncrob</tt>.

The fourth is <tt>text2nc</tt> which can be used to read small volumes
  (say up to a few thousand lines) of ASCII data and copy it into netCDF variables.
  It is also possible to use <tt>text2nc</tt> to create, modify and delete
  attributes.

This document does not cover other ways of using FAN. These include some local
  (CSIRO DAR) utilities (e.g. contouring program <tt>con_cif</tt>), the
  array-oriented languages IDL and J (for which there are FAN interfaces) and
  direct use of the C API (application programmer interface).

Simple Examples

Let us start with a simple netCDF file <tt>vec.nc</tt> which is printed
  (in CDL) as follows:

$ ncdump vec.nc
netcdf vec {
dimensions:
        n = UNLIMITED ; // (5 currently)
variables:
        float v(n) ;
data:
 v = 10 , 20.3 , 30.2 , 40.9 , 50  ;
}

Here `<tt>$</tt>' is the UNIX command-line prompt. The following
  uses <tt>nc2text</tt> to print the whole array <tt>v</tt>:

$ nc2text vec.nc v
10 20.3 30.2 40.9 50

Individual elements can be selected using subscripts. For example:

$ nc2text vec.nc 'v[0]'
10
$ nc2text vec.nc 'v[3]'
40.9

Several can be selected using a subscript consisting of a list of indices such
  as:

$ nc2text vec.nc 'v[0 3 1 3]'
10 40.9 20.3 40.9

We can write to a netCDF file using <tt>text2nc</tt>. The following
  changes the third element from 30.2 to 30.7 and then prints <tt>v</tt>:

$ echo 30.7 | text2nc vec.nc 'v[2]'
$ nc2text vec.nc v
10 20.3 30.7 40.9 50

Here <tt>text2nc</tt> reads ASCII text data from standard input, which
  in this case is a pipe connected to the standard output of <tt>echo</tt>.
  Since the dimension has <tt>UNLIMITED</tt> size, we can append values
  as follows:

$ echo 60.5 70.2 | text2nc vec.nc 'v[5 6]'
$ nc2text vec.nc v
10 20.3 30.7 40.9 50 60.5 70.2

Next we use <tt>ncrob</tt> to calculate and print the arithmetic mean
  of <tt>v</tt>.

$ ncrob -r am vec.nc v /
40.3714

The option <tt>-r am</tt> specifies that an arithmetic mean
  is to be calculated. The following example stores the mean in the same file,
  naming the variable <tt>v_mean</tt>:

$ ncrob -r am vec.nc v / v_mean
$ nc2text vec.nc v_mean
40.3714

The `<tt>/</tt>' separates the input from the output. If no output
  is specified then results are printed. In fact <tt>ncrob</tt> can be
  used in place of <tt>nc2text</tt> to print data from a netCDF file. E.g.

$ ncrob vec.nc v /
10 20.3 30.7 40.9 50 60.5 70.2
$ ncrob vec.nc v_mean /
40.3714

Finally we use <tt>ncmeta</tt> to print metadata. The shape is printed
  by:

$ ncmeta v vec.nc
5

and the following prints the variable name, dimension name and shape:

$ ncmeta -w vds v vec.nc
v n 5

What is New in Version 2?

The utility <tt>ncmeta</tt> is new.

There are significant enhancements to the utility <tt>ncrob</tt>. It
  can now print results as well as write them to netCDF files. (This means that
  <tt>nc2text</tt> is no longer really needed.) In version 1 the output
  FAN specification could only be a single (final) argument. There can now be
  zero (implying printed output) or more output arguments following a `<tt>/</tt>'
  which separates input arguments from output arguments. (The old convention is
  deprecated but still supported.) It is now possible to create new variables
  without specifying the <tt>-c</tt> option or an output filename. There
  is a facility for merging dimensions. There are several new options related
  to printing and similar to those of <tt>nc2text</tt>. A number of bugs
  in <tt>ncrob</tt> have been fixed, including one with a serious effect
  on speed.

FAN Language

High-level Syntax

A FAN specification can be either a single command-line argument or span several
  arguments. Use of multiple arguments decreases the need for quoting and allows
  use of UNIX wildcarding (a.k.a. globbing) facilities. A FAN
  specification can have any of the following forms:

      Syntax
      Meaning

      fanio <tt>/</tt> fanio
      netCDF input and netCDF output

      fanio <tt>/</tt>
      netCDF input and output to <tt>stdout</tt> (i.e. printed)

      fanio
      Either netCDF input or netCDF output (but not both)

where fanio is a FAN input/output specification, which has the form:

  pair <tt>;</tt> pair <tt>;</tt> pair
  <tt>;</tt> ...

  A semicolon (`<tt>;</tt>') has the same effect as commencing a new
  argument. Any sequence of one or more whitespace characters (space, tab, newline)
  is equivalent to a single space.

A pair can take any of the following forms:

  filename vas

  vas filename

  filename

  vas

A filename must contain at least one period (`<tt>.</tt>')
  to distinguish it from a variable name. This will be the case if netCDF filenames
  have a conventional suffix such as the recommended <tt>.nc</tt>. (In
  any case it is always possible to prefix a redundant `<tt>./</tt>'
  directory as in `<tt><b>./unconventional</b></tt>' or `<tt>/usr/./IdidItMyWay</tt>'!)

A vas is a variable or attribute specification which can
  have any of the following forms:

  var

  var<tt>[</tt>subscript<tt>,</tt> subscript<tt>,</tt>
  subscript<tt>,</tt> ...<tt>]</tt>

  var<tt>[</tt>subscript<tt>,</tt> subscript<tt>,</tt>
  subscript<tt>,</tt> ...<tt>)</tt>

  var<tt>(</tt>subscript<tt>,</tt> subscript<tt>,</tt>
  subscript<tt>,</tt> ...<tt>]</tt>

  var<tt>(</tt>subscript<tt>,</tt> subscript<tt>,</tt>
  subscript<tt>,</tt> ...<tt>)</tt>

  var<tt>:</tt>att

  <tt>:</tt>att

  where var is a variable name or ID number and att is an attribute
  name or ID number. It is usually more convenient to identify variables, attributes
  and dimensions by name rather than ID number. The use of ID numbers is discussed
  in Section Using ID Numbers. Attributes are discussed
  in Section Attributes.

A pair without a filename or vas uses that of the previous
  pair. The first pair has no effect by itself unless it contains both a filename
  and a vas. Thus the following all access the same values:

$ nc2text 'vec.nc v[0 4]'
10 50
$ nc2text 'v[0 4] vec.nc'
10 50
$ nc2text vec.nc 'v[0 4]'
10 50
$ nc2text 'v[0 4]' vec.nc
10 50
$ nc2text '  v [  0   4 ]      vec.nc  '
10 50

The following are equivalent ways of concatenating variables <tt>v</tt>
  and <tt>v_mean</tt>:

$ nc2text 'vec.nc v' 'vec.nc v_mean'
10 20.3 30.7 40.9 50 60.5 70.2
40.3714
$ nc2text 'vec.nc v' 'v_mean'
10 20.3 30.7 40.9 50 60.5 70.2
40.3714
$ nc2text 'vec.nc v; v_mean'
10 20.3 30.7 40.9 50 60.5 70.2
40.3714
$ nc2text vec.nc v v_mean
10 20.3 30.7 40.9 50 60.5 70.2
40.3714

Now let us copy file <tt>vec.nc</tt> to <tt>vec_new.nc</tt> and
  then demonstrate concatenation of data from different files:

$ cp vec.nc vec_new.nc
$ nc2text v vec.nc vec_new.nc
10 20.3 30.7 40.9 50 60.5 70.2
10 20.3 30.7 40.9 50 60.5 70.2
$ nc2text v vec*.nc
10 20.3 30.7 40.9 50 60.5 70.2
10 20.3 30.7 40.9 50 60.5 70.2

Note the use of UNIX wildcarding facilities in the latter example
  using the metacharacter `<tt>*</tt>' in <tt>vec*.nc</tt>
  which matches both <tt>vec.nc</tt> and <tt>vec_new.nc</tt>.

Subscripts

As mentioned in Section High level Syntax,
  subscripts are enclosed by either `<tt><b>[</b></tt>' or `<tt>(</tt>'
  on the left and either `<tt><b>]</b></tt>' or `<tt>)</tt>' on
  the right.

A left bracket `<tt>[</tt>' implies the C convention of starting
  subscripts at 0; while a left parenthesis `<tt>(</tt>' implies the
  Fortran convention of starting at 1. This starting value of 0 or 1 is called
  the index origin. A mnemonic to associate left with index
  origin is an x-axis with the origin on the left.

The right hand delimiter controls the relative significance of multiple dimensions.
  A `<tt>]</tt>' implies conventional row-major (or lexicographic)
  order in which the rightmost subscript varies fastest; while a `<tt>)</tt>'
  implies the Fortran convention of column-major order in which the leftmost
  subscript varies fastest.

So far our examples have involved only a single dimension. Now consider a netCDF
  file <tt>mat.nc</tt> containing a 2-dimensional array (i.e. a matrix).
  We print it as follows:

$ ncdump mat.nc
netcdf mat {
dimensions:
        row = 2 ;
        col = 3 ;
variables:
        short M(row, col) ;
data:
 M =
  11, 12, 13,
  21, 22, 23 ;
}

The following are equivalent ways of printing the final element:

$ nc2text 'mat.nc M[1,2]'
23
$ nc2text 'mat.nc M(2,3]'
23
$ nc2text 'mat.nc M(3,2)'
23
$ nc2text 'mat.nc M[2,1)'
23

Subscript values can be less than the index origin and are then relative to
  the end. So the final element could also be accessed by:

$ nc2text 'mat.nc M[-1,-1]'
23
$ nc2text 'mat.nc M(0,0)'
23

As we have seen before, a subscript can contain a list of indices. Thus one
  could use any of the following to select all rows, but exclude the middle column:

$ nc2text mat.nc 'M[0 1,0 2]'
11 13
21 23
$ nc2text mat.nc 'M(1 2,1 3]'
11 13
21 23
$ nc2text mat.nc 'M(1 3,1 2)'
11 13
21 23

Triplet Notation

A sequence of indices forming an arithmetic progression as in

$ nc2text vec.nc 'v[0 2 4 6]'
10 30.7 50 70.2

can be specified using a generalization of Fortran 90 triplet notation,
  in this case:

$ nc2text vec.nc 'v[0:6:2]'
10 30.7 50 70.2

The triplet <tt>0:6:2</tt> means 0 to 6 in steps of 2. A triplet
  can take two forms:

  start<tt>:</tt>finish<tt>:</tt>stride

  start<tt>:</tt>finish

  The second form implies a stride of 1. It is possible to omit start
  and/or finish. Let  <var>I</var>  be the index-origin (0
  or 1). If the stride is positive then start defaults to  <var>I</var>
  (i.e. first element) and finish to  <var>I</var>-1  (i.e.
  final element). These are reversed for a negative stride; start defaults
  to  <var>I</var>-1  and finish to  <var>I</var>. E.g.

$ nc2text vec.nc v
10 20.3 30.7 40.9 50 60.5 70.2
$ nc2text vec.nc 'v[:6:2]'
10 30.7 50 70.2
$ nc2text vec.nc 'v[0::2]'
10 30.7 50 70.2
$ nc2text vec.nc 'v[::2]'
10 30.7 50 70.2
$ nc2text vec.nc 'v[0:2]'
10 20.3 30.7
$ nc2text vec.nc 'v[:2]'
10 20.3 30.7
$ nc2text vec.nc 'v[2:]'
30.7 40.9 50 60.5 70.2
$ nc2text vec.nc 'v[::-1]'
70.2 60.5 50 40.9 30.7 20.3 10

Note how the latter example reverses the order. A triplet can wrap-around the
  start or end. This is useful with cyclic dimensions such as longitude. Wrap-around
  is shown by:

$ nc2text vec.nc 'v[3:1]'
40.9 50 60.5 70.2 10 20.3
$ nc2text vec.nc 'v[1:3:-1]'
20.3 10 70.2 60.5 50 40.9

But the following does not imply wrap-around:

$ nc2text vec.nc 'v[0:-1:1]'
10 20.3 30.7 40.9 50 60.5 70.2

since <tt>-1</tt> means final (i.e. same as <tt>6</tt>).
  Each subscript can contain any number of triplets and individual values. The
  colon (<tt>:</tt>) operator has higher precedence than concatenation.
  This is shown by the following:

$ nc2text vec.nc 'v[2 :4]'
30.2 40.9 50

which is equivalent to:

$ nc2text vec.nc 'v[2:4]'
30.2 40.9 50

However parentheses can be used to override this precedence rule. E.g.

$ nc2text vec.nc 'v[2 (:4)]'
30.2 10 20.3 30.2 40.9 50

Omitting Subscripts

An omitted subscript implies the whole dimension. Thus we can print the first
  row of <tt>mat</tt> as follows:

$ nc2text mat.nc 'M[0]'
11 12 13

and exclude the middle column by:

$ nc2text mat.nc 'M[,0 -1]'
11 13
21 23

Dimension Names

Dimension names play an important role in FAN. Instead of:

$ nc2text mat.nc 'M(2 1,1 3]'
21 23
11 13

one can use:

$ nc2text mat.nc 'M(row=2 1,col=1 3]'
21 23
11 13

This is clearer for human readers. But specifying dimension names also provides
  the important facility of transposing dimensions. For example this allows <tt>ncrob</tt>
  to produce statistics (e.g. means) for rows as well as the normal columns. To
  transpose the above matrix, one could specify:

$ nc2text mat.nc 'M(col=1 3,row=2 1]'
21 11
23 13

since the order in which dimensions are specified controls their order in the
  output. To transpose a whole matrix one need only specify the dimension names
  as in the following:

$ nc2text mat.nc 'M[col,row]'
11 21
12 22
13 23

or using column-major order:

$ nc2text mat.nc 'M(row,col)'
11 21
12 22
13 23

In fact only one dimension name is needed, since any not mentioned are appended
  in their input order. E.g.

$ nc2text mat.nc 'M[col]'
11 21
12 22
13 23

Indirect Indexing

So far we have located elements using direct index values. FAN also allows
  an indirect method using coordinate variables (i.e. variables with
  the same names as dimensions). Consider the following geographic netCDF file
  <tt>geog.nc</tt>:

$ ncdump geog.nc
netcdf geog {
dimensions:
        lat = 3 ;
        lon = 4 ;
variables:
        float lat(lat) ;
                lat:units = "degrees_north" ;
        float lon(lon) ;
                lon:units = "degrees_east" ;
        double tsur(lat, lon) ;
data:
 lat = -45 , 0 , 45  ;
 lon = -180 , -90 , 0 , 90  ;
 tsur =
  11, 12, 13, 14,
  21, 22, 23, 24,
  31, 32, 33, 34 ;
}

FAN provides several indirect indexing operators. Perhaps the most
  useful of these is `<tt>~</tt>', which gives the index of the coordinate
  value closest to its argument. Thus:

$ nc2text geog.nc 'lat[~-40]'
-45

prints the latitude closest to 40�S and

$ nc2text geog.nc 'tsur[~-40,~10]'
13

prints the element of <tt>tsur</tt> closest to the point 40�S, 10�E.
  Note that FAN knows nothing about circular wrap-around and does not consider
  360� to be equal to 0�. The following shows how indirect indexing can be used
  within triplets:

$ nc2text geog.nc 'tsur[ lat = ~90:~-90:-2 , lon = ~10: ]'
33 34
13 14

This gives every second latitude from that closest the north pole to that closest
  the south pole, and all longitudes from that closest to 10�E to the final one.
  The other indirect indexing operators are as follows:

    <tt>@ max <</tt>
    index value corresponding to maximum coordinate value less than argument

    <tt>@ max <=</tt>
    index value corresponding to maximum coordinate value less than or equal
      to argument

    <tt>@ min ></tt>
    index value corresponding to minimum coordinate value greater than argument

    <tt>@ min >=</tt>
    index value corresponding to minimum coordinate value greater than or
      equal to argument

Thus the following prints the minimum longitude greater than 10�E:

$ nc2text geog.nc 'lon[@ min > 10]'
90

and the following retrieves the rows from the maximum latitude less than
  or equal to 30�N to the closest latitude to 90�N, and the columns
  from the second (i.e 1 with respect to index origin of 0) to minimum longitude
  greater than 0.

$ nc2text geog.nc 'tsur[lat= @max<=30 : ~90, lon= 1 : @min > 0]'
22 23 24
32 33 34

Offsets

It is possible to specify offsets using an expression of the form

  index <tt>+</tt> offset

  where offset is an integer constant (which can be negative). The offset
  must be the right hand argument of `<tt><b>+</b></tt>'. Note that this `<tt>+</tt>'
  operator has even higher precedence than `<tt>:</tt>'. Here are some
  examples of the use of offsets:

$ nc2text geog.nc 'lon[ ~-100 + -1 : ~-360 + 2 ]'
-180 -90 0

prints the longitudes from that one before the closest to 100�W to
  that two beyond the closest to 360�W. Note how the negative offset
  is specified as `<tt>+ -1</tt>', which is not equivalent
  to `<tt>-1</tt>' as in:

$ nc2text geog.nc 'lon[ ~-100-1 : ~-360 + 2 ]'
-90 90 -180 -90 0

which is equivalent to both the following (Note the wrap-around.):

$ nc2text geog.nc 'lon[ (~-100) (-1:~-360 + 2) ]'
-90 90 -180 -90 0
$ nc2text geog.nc 'lon[ 1 3:2 ]'
-90 90 -180 -90 0

One use for offsets is to append along the <tt>UNLIMITED</tt> dimension
  without needing to know its current size. The expression `<tt>-1+1</tt>'
  represents the index value for appending immediately after the current final
  record. Thus we could append a value to variable <tt>v</tt> in file <tt>vec_new.nc</tt>
  (whose <tt>UNLIMITED</tt> dimension <tt>n</tt> has the current
  size 7) by:

$ echo 80 | text2nc 'vec_new.nc v[-1 + 1]'
$ nc2text 'vec_new.nc v'
10 20.3 30.7 40.9 50 60.5 70.2 80

Then we could append two more values by:

$ echo 90 100.1 | text2nc 'vec_new.nc v[ -1 + 1 : -1 + 2 ]'
$ nc2text 'vec_new.nc v'
10 20.3 30.7 40.9 50 60.5 70.2 80 90 100.1

giving a new size of 10 for the <tt>UNLIMITED</tt> dimension.

Coordinate Variable Unit Conversion

In file <tt>geog.nc</tt> the <tt>units</tt> attribute is <tt>degrees_north</tt>
  for <tt>lat</tt> and <tt>degrees_east</tt> for <tt>lon</tt>.
  One may want to specify coordinate values in some other units. The following
  shows how this can be done by appending the unit (enclosed in braces i.e. `<tt>{}</tt>')
  to the value:

$ nc2text geog.nc 'tsur[ lat=~0.8{radian}, lon = ~ -1.5 { radian } ]'
32

giving the value at the point closest to latitude 0.8 radians north and longitude
  1.5 radians west. This unit conversion (like that during FAN input and output)
  is done using the Unidata units library discussed in Appendix C of  NetCDF
  User's Guide.

Attributes

As noted in Section High level Syntax
  an attribute vas can take two forms:

  var<tt>:</tt>att

  <tt>:</tt>att

  As in CDL, the latter denotes a global attribute. The following writes
  the global attribute <tt>title</tt> and then reads and prints it:

$ echo 'Sample geographic file' | text2nc -h 'geog.nc :title'
$ nc2text 'geog.nc :title'
Sample geographic file

(The <tt>-h</tt> flag means `Do not append a line to the global
  attribute <tt>history</tt>'.)

Attributes cannot have subscripts, so there is no way of accessing only part
  of an attribute. Attributes are automatically created if they do not exist and
  their type and size can be changed. The following gives variable <tt>lat</tt>
  the new attribute <tt>valid_range</tt> (with type <tt>float</tt>)
  and then prints it:

$ echo -90 90 | text2nc -h -t float 'geog.nc lat:valid_range'
$ nc2text 'geog.nc lat:valid_range'
-90 90

The following gives variable <tt>lat</tt> another new attribute <tt>foo</tt>
  (by copying variable <tt>v</tt> from file <tt>vec.nc</tt>), then
  modifies it, then deletes it.

$ nc2text 'vec.nc v[:4]' | text2nc -h -t double 'geog.nc lat:foo'
$ nc2text 'geog.nc lat:foo'
10 20.3 30.2 40.9 50
$ echo 'Hello' | text2nc -h 'geog.nc lat:foo' # Modify attribute 'lat:foo'
$ nc2text 'geog.nc lat:foo'
Hello
$ text2nc -h 'geog.nc lat:foo' < /dev/null    # Delete attribute 'lat:foo'

Note how one can delete attributes by changing their size to 0. The file <tt>/dev/null</tt>
  is a standard UNIX pseudo-file that is empty for input.

Using ID Numbers for Variables, Dimensions and Attributes

It is possible to use ID numbers in place of names for variables, dimensions
  and attributes. However dimension ID numbers must be followed by <tt>=</tt>
  so they can be distinguished from index values. ID numbers begin at 0 regardless
  of the index origin. Negative values are relative to the end, which is represented
  by <tt>-1</tt>.

There are some situations where ID numbers are more convenient than names.
  For example, one might adopt the convention that coordinate variables should
  be defined first, after which there should be only a single other (main) variable
  in each file. A shell-script to process such files can refer to the main variable
  as <tt>-1</tt>. The following shows the use of such a variable ID number:

$ nc2text geog.nc -1
11 12 13 14
21 22 23 24
31 32 33 34

The following prints the first attribute of the second variable:

$ nc2text geog.nc '1:0'
degrees_east

The following Korn shell script <tt>pratts</tt> prints all the non-global
  attributes in the files specified by its arguments.

$ cat pratts
#!/bin/ksh
for FILE
do
    integer VARID=0
    # Following true if variable VARID exists
    while VARNAME="$(ncmeta -s -w v $FILE $VARID)"; test -n "$VARNAME"
    do
        integer ATTID=0
        # Following true if attribute ATTID exists
        while ATTNAME="$(ncmeta -s -w a $FILE $VARID:$ATTID)"; test -n "$ATTNAME"
        do
        print -n "$FILE $VARNAME:$ATTNAME "
        nc2text $FILE "$VARNAME:$ATTNAME"
        (( ATTID += 1 ))
        done
        (( VARID += 1 ))
    done
done

We can use <tt>pratts</tt> on file <tt>geog.nc</tt> as follows:

$ pratts geog.nc
geog.nc lat:units degrees_north
geog.nc lat:valid_range -90 90
geog.nc lon:units degrees_east

FAN Utilities

Introduction to Utilities

This section provides a more detailed description of the four FAN utilities,
  <tt>nc2text</tt>, <tt>text2nc</tt>, <tt>ncmeta</tt> and
  <tt>ncrob</tt>, commencing with some features common to several utilities.
  The usage summaries in Sections nc2text Usage,
  text2nc Usage, ncmeta Usage and ncrob Usage can be printed by entering the command
  name without any arguments.

All netCDF types (<tt>char, byte, short, long, float</tt> and <tt>double</tt>)
  can be read and written. During input/output there is automatic conversion to
  or from type <tt>double</tt>, which is used for internal storage and
  processing.

Options Common to several Utilities

The two flags <tt>-h</tt> and <tt>-H</tt> specify what is to
  be written to the global attribute <tt>history</tt>. The <tt>-h</tt>
  flag means `Do not write any history'. The <tt>-H</tt> flag
  means `Exclude time-stamp and user-name (<tt>LOGNAME</tt>) from
  history'. This flag is useful in program testing, since it causes the
  same values to be written to <tt>history</tt> each time, thus facilitating
  comparison of actual output with that expected.

Section 4.5 of  NetCDF
  User's Guide explains the two aspects of error-handling: suppression
  of error messages and fatality of errors. The default mode is verbose
  and fatal. Non-verbose (silent) mode is set by flag <tt>-s</tt>.
  Non-fatal (persevere) mode is set by flag <tt>-p</tt>.

The <tt>-e</tt> flag means `Write error messages to <tt>stdout</tt>
  not <tt>stderr</tt>'.

The option `<tt>-t</tt> type' sets the data-type for new
  variables or attributes. Valid values are <tt>char, byte, short, long, float</tt>
  and <tt>double</tt>. These can be abbreviated to their first letter.

The option `<tt>-u</tt> unit' sets the unit of measure
  for ASCII text data, providing conversion to or from those defined by netCDF
  <tt>units</tt> attributes.

Scaling and Unit Conversion

All netCDF input and output values are transformed by a linear equation defined
  by the attributes <tt>add_offset</tt>, <tt>scale_factor</tt> and
  <tt>units</tt>; together with any unit defined by the <tt>-u</tt>
  option mentioned above. The output <tt>units</tt> attribute is defined
  or modified in some situations such as when it is undefined but the corresponding
  input attribute is defined.

All unit conversion is done using the Units Library documented in
  Appendix C of  NetCDF
  User's Guide. The environment variable <tt>UDUNITS_PATH</tt>
  can be used to specify a non-standard units file. (See <tt>man</tt> document
  <tt>udunits(3)</tt>.)

Missing Values

Values read from a netCDF file are considered missing if outside the valid
  range defined by the attribute <tt>valid_range</tt> or the attributes
  <tt>valid_min</tt>, and <tt>valid_max</tt>. If these do not define
  either the minimum or the maximum then an attempt is made to define it based
  on the principle that the missing value must be outside the valid range.
  The missing value is defined by the attribute <tt>missing_value</tt>,
  or if this is undefined then the fill value (defined by attribute <tt>_FillValue</tt>
  if defined, otherwise the default fill value for the data type).

Environment Variables

The environment variable <tt>UDUNITS_PATH</tt> was mentioned in Section
  Scaling. The environment variable <tt>COLUMNS</tt>
  (default: 80) defines the page width and is used to print data of type <tt>character</tt>.

nc2text

This utility prints variable and attribute values from netCDF files.

Usage

Usage: nc2text [-eps] [-f %s] [-m %s] [-n %d] [-u %s] <FANI>
<FANI> netCDF FAN specification for input
-e            Write error messages to stdout not stderr
-p            Persevere after errors
-s            Silent mode: Suppress warning messages
-f <string>:  Format for output (default: C_format attribute ("%G" if none))
-m <string>:  Missing value for output (default: _ )
-n <integer>: Number of fields per line of output (default: 10 if numeric)
              (Environment variable COLUMNS defines default for characters)
-u <string>:  Unit of measure for output (default: unit in file)

Examples

The following prints the first three elements of variable <tt>v</tt>
  of file <tt>vec.nc</tt>:

$ nc2text 'vec.nc v[0 1 2]'
10 20.3 30.2

The following uses <tt>text2nc</tt> to

set attribute <tt>v:units</tt> to `<tt>degF</tt>'

set attribute <tt>v:valid_min</tt> to -460�F (just below 0�K)

modify <tt>v[2]</tt> so it is less than this valid minimum i.e. missing.

$ echo degF | text2nc vec.nc 'v:units'
$ echo -460 | text2nc -t float vec.nc 'v:valid_min'
$ echo -999 | text2nc vec.nc 'v[2]'

Then we print four Celsius temperatures per line. The text `<tt>MISSING</tt>'
  is printed for missing values. Normal values are printed using the C format
  <tt>%8.4f</tt> (equivalent to the Fortran format <tt>F8.4</tt>
  i.e 4 decimal places with a total field width of 8 characters).

$ nc2text -f '%8.4f' -m ' MISSING' -n 4 -u degC vec.nc 'v[:4]'
-12.2222  -6.5000  MISSING   4.9444
 10.0000

ncmeta

This utility prints metadata from netCDF files. This metadata can include rank,
  shape, file names, variable names, dimension names and attribute names.

Usage

Usage: ncmeta [-eps] [-w <LETTERS>] <FANI>
<FANI> netCDF FAN specification for input
-e            Write error messages to stdout not stderr
-p            Persevere after errors
-s            Silent mode: Suppress warning messages
-w <LETTERS>: What to print using following (default: s)
                 a: attribute names
                 d: dimension names
                 f: file names
                 r: rank (number of dimensions)
                 s: shape (dimension sizes)
                 v: variable names

Example: ncmeta -w fvs abc.nc var1 var2

Examples

The following examples print the shape of the specified variables:

$ ncmeta vec.nc v
5
$ ncmeta geog.nc tsur
3 4

The following example prints the filename, variable name, rank, dimensions
  and shape of the specified variables:

$ ncmeta -w fvrds vec.nc v 'geog.nc tsur' lat lon
vec.nc v 1 n 5
geog.nc tsur 2 lat lon 3 4
geog.nc lat 1 lat 3
geog.nc lon 1 lon 4

The following example prints the variable name and attribute name of the first
  (0) attribute of the first (0) variable:

$ ncmeta -w va geog.nc '0:0'
lat units

ncrob

This utility reads data from one or more netCDF variables, performs some process
  on it and then either prints the result or writes it to one or more netCDF variables.
  The type of process is defined by option `<tt>-r</tt> string',
  where string is one of the following:

      <tt>am</tt>
      arithmetic mean

      <tt>broadcast</tt>
      cyclic copy

      <tt>count</tt>
      number of non-missing values

      <tt>fill</tt>
      fill with missing values

      <tt>gm</tt>
      geometric mean

      <tt>max</tt>
      maximum

      <tt>min</tt>
      minimum

      <tt>prod</tt>
      product

      <tt>sd</tt>
      unadjusted standard deviation (divisor is  <var>n</var> )

      <tt>sd1</tt>
      adjusted standard deviation (divisor is  <var>n</var>-1 )

      <tt>sum</tt>
      sum

      <tt>sum2</tt>
      sum of squares of values

A <tt>broadcast</tt> copies successive elements from input to output.
  Whenever the end of input is reached, reading begins again at the start of input.
  The whole process continues until reaching the end of output.

A <tt>fill</tt> simply fills the output variable with missing values.
  There must be input, although it is used only to define the shape of new variables.

The other processes are all reductions, in the sense that they reduce
  the rank (number of dimensions). The number of input elements ( <var>I</var> )
  must be a multiple of both the number of output elements ( <var>N</var> )
  and the number of weights ( <var>M</var> ) (if any, as specified by
  option <tt>-w</tt>).

If the process is <tt>count</tt> and there are no weights then the result
  is the number of non-missing values. If there are weights then the result is
  the sum of the weights of the non-missing values.

Let vector  <var>X</var>0, <var>X</var>1, ..., <var>
  X</var><var>i</var>, ..., <var>X</var><var> I</var>-1
  represent the selected input data elements in the specified order. Similarly,
  let vector  <var>Y</var>0, <var>Y</var>1, ... <var>
  Y</var><var>j</var>, ..., <var>Y</var><var> N</var>-1
  represent the resultant output data. Let  <var>n</var> = <var>I</var> � <var>N</var>.

If the process is <tt>sum</tt> and there are no weights then

    <var>Y</var><var>j</var> =  Sum<var>i</var>=0,<var>n</var>-1 <var>X</var>
  <var>Ni</var>+<var>j</var>

If weights  <var>W</var>0, <var>W</var>1, ..., <var>
  W</var><var>k</var>, ..., <var>W</var><var> M</var>-1
  are defined and  <var>m</var> = <var>I</var> � <var>M</var>
  then

    <var>Y</var><var>j</var> =  Sum<var>i</var>=0,<var>n</var>-1 <var>W</var>
  floor((<var>Ni</var>+<var>j</var>)/m)<var>X</var>
  <var>Ni</var>+<var>j</var>

where  floor( <var>x</var> )  represents
  the floor of  <var>x</var>  i.e. the greatest integer  <= <var>x</var>.

This is calculated using the following algorithm:

 <var>n</var>  <tt>:=</tt>  <var>I</var>�<var>N</var>

   <var>m</var>  <tt>:=</tt>  <var>I</var>�<var>M</var>

  for  <var>j</var>  from 0 to  <var>N</var>-1

  <tt>   </tt>  <var>Y</var><var>j</var>
  <tt>:=</tt> 0

  for  <var>i</var>  from 0 to  <var>I</var>-1

  <tt>   </tt>  <var>j</var>  <tt>:=</tt>  <var>i</var> mod <var>n</var>

  <tt>   </tt>  <var>k</var>  <tt>:=</tt>  floor( <var>i</var>/m )

  <tt>   </tt> if  <var>Y</var><var>j</var> �=
  <tt>missing_value</tt>

  <tt>   </tt> <tt>   </tt> if <tt>valid_min</tt>
   <= <var>X</var><var>i</var> <=  <tt>valid_max</tt>

  <tt>   </tt> <tt>   </tt> <tt>   </tt>
   <var>Y</var><var>j</var>  <tt>:=</tt>  <var>Y</var><var>j</var> + <var>W</var>
  <var>k</var> <var>X</var><var>i</var>

  <tt>   </tt> <tt>   </tt> else if <tt>suddenDeath</tt>

  <tt>   </tt> <tt>   </tt> <tt>   </tt>
   <var>Y</var><var>j</var>  <tt>:=</tt> <tt>missing_value</tt>

Note that this definition of  <var>k</var>  means that the first
   <var>m</var>  elements have the first weight  <var>W</var>0 ,
  the next  <var>m</var>  have the second weight  <var>W</var>1 ,
  and so on.

As an example consider an input array which is a matrix  <var>A</var>
  with  <var>R</var>  rows and  <var>C</var>  columns. Thus
   <var>I</var>=<var>RC</var>. If we want column sums then the output vector
  would be of length  <var>C</var>  i.e.  <var>N</var>=<var>C</var>.
  Now  <var>n</var>= <var>I</var> � <var>N</var> = <var>
  R</var>. So the unweighted sum is

    <var>Y</var><var>j</var> =  Sum<var>i</var>=0,<var>R</var>-1 <var>X</var>
  <var>Ci</var>+<var>j</var> = Sum <var>i</var>=0,<var>R</var>-1 <var>A</var><var>ij</var>

and the weighted sum is

    <var>Y</var><var>j</var> =  Sum<var>i</var>=0,<var>R</var>-1 <var>W</var>
  floor((<var>Ci</var>+<var>j</var>)/C) <var> X</var><var>Ci</var>+<var>j</var> = Sum
  <var>i</var>=0,<var>R</var>-1 <var>W</var><var>i</var> <var>
  A</var><var>ij</var>

If the process is <tt>prod</tt> and there are no weights then

    <var>Y</var><var>j</var> =  Product<var>i</var>=0,<var>n</var>-1 <var>X</var>
  <var>Ni</var>+<var>j</var>

If weights are defined then

    <var>Y</var><var>j</var> =  Product<var>i</var>=0,<var>n</var>-1 <var>X</var>
  <var>Ni</var>+<var>j</var> <var>W</var> floor((<var>Ni</var>+<var>j</var>)/m)

In general the shape (dimension vector) of the destination should match the
  trailing dimensions of the source. Then the reduction process operates over
  those leading dimensions absent from the destination.

Note that FAN allows you to transpose dimensions by specifying them in an order
  different from that in the file. Thus the leading source dimensions are those
  specified first. The order of the remaining dimensions must match those of the
  destination.

The other reduction processes are treated similarly. However <tt>min</tt>
  and <tt>max</tt> do not allow weights.

If the <tt>-m</tt> flag is specified then the result is missing if any
  of the values it depends on is missing (sudden death mode). Otherwise
  missing values are omitted (filter mode) i.e. essentially treated as
  having a weight of 0.

The <tt>-b</tt> option sets the size of the input buffer. This can improve
  efficiency when reading very large variables.

The <tt>-c</tt> option creates a new destination variable with the specified
  rank (number of dimensions). If the variable already exists then this option
  is ignored. If the destination file does not exist then it is created. The variable
  is created with the same attributes as the (first if several) source variable,
  and the specified number of its trailing dimensions, together with any associated
  coordinate variables. However a broadcast is slightly different in that a new
  leading dimension is created from the leading source dimensions by taking the
  product of their sizes (so the total number of elements is unchanged) and concatenating
  their names. The data-type of the new variable is specified using option <tt>-t</tt>
  and defaults to the type of the source variable.

Usage

Usage: ncrob [options] <FANI> / <FANO>
<FANI>: FAN specification for input
<FANO>: FAN specification for output (default: stdout)
-e            Write error messages to stdout not stderr
-H            Exclude time-stamp & LOGNAME from history
-h            Do not write history
-m            If any value missing then result missing
-p            Persevere after errors
-s            Silent mode: Suppress warning messages
-b <int>:     Max. buffer size (Kbytes) (default: 512)
-c <int>:     Rank (decrement if < 0) of any Created variable including stdout
              (default: input rank for broadcast, else -1)
-f <string>:  Format for stdout (default: C_format attribute ("%G" if none))
-M <string>:  Missing value for stdout (default: _ )
-n <integer>: Number of fields per line for stdout (default: 10 if numeric)
              (Environment variable COLUMNS defines default for characters)
-r <string>:  Reduction type (am broadcast count fill gm max min prod
               sd sd1 sum sum2) (default: broadcast)
-t char|byte|short|long|float|double: new variable type (default: input type)
-u <string>:  Unit of measure for stdout (default: unit in file)
-w <reals>:   Weight vector(e.g. -w '3 1.5 .8')

If the `<tt>/</tt>' is omitted then the final argument is taken
  as <tt><FANO></tt>. (This version 1 convention is deprecated.)
  If <tt><FANO></tt> does not specify a filename or variable name
  then the first one in <tt><FANI></tt> is used.

Examples

The following prints the variable <tt>M</tt> in file <tt>mat.nc</tt>:

$ ncrob mat.nc M /
11 12 13
21 22 23

The following prints the column sums, row means and overall product:

$ ncrob -r sum mat.nc M /       # sum of each column
32 34 36
$ ncrob -r am mat.nc 'M[col]' / # arithmetic mean of each row
12 22
$ ncrob -r prod -c 0 -f '%.0f' mat.nc M / # overall product
18234216

The first two commands have no <tt>-c</tt> option, so the rank of the
  result is one less than that of the input. The third specifies <tt>-c 0</tt>,
  so the result has rank 0, i.e. is scalar. The following attempts to put this
  same data into three new variables in the same file:

$ ncrob -h -r sum mat.nc M / col_sum
$ ncrob -h -r am mat.nc 'M[col]' / row_am
$ ncrob -h -r prod -c 0 mat.nc M / prod
$ ncdump mat.nc
netcdf mat {
dimensions:
        row = 2 ;
        col = 3 ;
variables:
        short M(row, col) ;
        short col_sum(col) ;
        short row_am(row) ;
        short prod ;
data:
 M =
  11, 12, 13,
  21, 22, 23 ;
 col_sum = 32, 34, 36 ;
 row_am = 12, 22 ;
 prod = _ ;
}

Why is <tt>prod</tt> dumped as <tt>_</tt> (i.e. fill) rather
  than 18234216 as before? The problem is that <tt>ncrob</tt> has created
  a new variable of the same type as the source variable, which in this case is
  <tt>short</tt> and incapable of storing such a large number. The solution
  is to specify the type using the <tt>-t</tt> option. Let's also create
  a new file <tt>prod.nc</tt>. E.g.

$ ncrob -h -r prod -c 0 -t long mat.nc M / prod.nc prod
$ ncdump prod.nc
netcdf prod {
variables:
        long prod ;
data:
 prod = 18234216 ;
}

Next let's calculate a weighted mean of each column. Let's give the
  first row twice the weight of the second:

$ ncrob -r am -w '2 1' M mat.nc /
14.3333 15.3333 16.3333

Thus the mean of the first column is (2 * 11 + 1 * 21)/3 = 14.3333. Negative
  weights can be used to obtain differences. E.g.

$ ncrob -r sum -w '1 -1' M mat.nc /            # row1 - row2
-10 -10 -10
$ ncrob -r sum -w '1 -1' 'M(col=3 1]' mat.nc / # col3 - col1

Finally we demonstrate broadcasting. Let's first copy the matrix <tt>M</tt>
  to two variables in a new file called <tt>new.nc</tt>. One new variable
  has the same name (<tt>M</tt>) and shape. The other is named <tt>V</tt>
  and is a vector with the new dimension <tt>row_col</tt> formed from dimensions
  <tt>row</tt> and <tt>col</tt>.

$ ncrob -h M mat.nc / new.nc
$ ncrob -h -c 1 M mat.nc / new.nc V
$ ncdump new.nc
netcdf new {
dimensions:
        row = 2 ;
        col = 3 ;
        row_col = 6 ;
variables:
        short M(row, col) ;
        short V(row_col) ;
data:
 M =
  11, 12, 13,
  21, 22, 23 ;
 V = 11, 12, 13, 21, 22, 23 ;
}

Now let's broadcast the variable <tt>col_sum</tt> in file <tt>mat.nc</tt>
  to these variables <tt>M</tt> and <tt>V</tt> in the file <tt>new.nc</tt>:

$ ncrob -h mat.nc col_sum / new.nc M V
$ ncdump new.nc
netcdf new {
dimensions:
        row = 2 ;
        col = 3 ;
        row_col = 6 ;
variables:
        short M(row, col) ;
        short V(row_col) ;
data:
 M =
  32, 34, 36,
  32, 34, 36 ;
 V = 32, 34, 36, 32, 34, 36 ;
}

Four copies of the input were needed to fill the output.

text2nc

This utility reads ASCII text data from standard input and writes it to a netCDF
  variable or attribute. The netCDF file and variable must already exist. However,
  as discussed in Section Attributes, <tt>text2nc</tt> can create
  attributes, delete them, and modify their type, size and value. If end-of-input
  occurs before end-of-output then the input values are recycled.

Usage

Usage: text2nc [-eHhps] [-m %f] [-u %s] <FANO>
<FANO>: netCDF FAN specification for output
-e           Write error messages to stdout not stderr
-H           Exclude time-stamp & LOGNAME from history
-h           Do not write history
-p           Persevere after errors
-s           Silent mode: Suppress warning messages
-m <real>:   Missing value for input (default: 1.79769E+308)
-t char|byte|short|long|float|double: data-type (for attributes only)
             (default: double for numeric input data, else char)
-u <string>: Unit of measure for input (default: unit in file)

Examples

Let's start with the following file:

$ ncdump vec.nc
netcdf vec {
dimensions:
        n = UNLIMITED ; // (5 currently)
variables:
        float v(n) ;
data:
 v = 10 , 20.3 , 30.2 , 40.9 , 50  ;
}

Let's assume these data are Celsius temperatures, so we define a valid
  minimum by:

$ echo -273.2 | text2nc -h vec.nc 'v:valid_min'

Then we modify two existing values:

$ echo 15 17 | text2nc -h -u degC vec.nc 'v[0 3]'
$ ncdump vec.nc
netcdf vec {
dimensions:
        n = UNLIMITED ; // (5 currently)
variables:
        float v(n) ;
                v:valid_min = -273.2 ;
                v:units = "degC" ;
data:
 v = 15 , 20.3 , 30.2 , 17 , 50  ;
}

Note that the <tt>units</tt> attribute was created because we specified
  <tt>-u degC</tt>, but there was no existing <tt>units</tt>
  attribute. Now let's append three values and print the resulting <tt>v</tt>:

$ echo -999 32 1e9 | text2nc -h -u degF -m 1e9 vec.nc 'v[-1+1:-1+3]'
$ nc2text -f '%0.1f' vec.nc v
15.0 20.3 30.2 17.0 50.0 _ 0.0 _

The first value (<tt>-999</tt>) is treated as missing because (even
  after conversion to Celsius) it is less than the valid mininum of <tt>-273.2</tt>.
  The second value (32�F) is converted to 0�C. The third value (<tt>1e9</tt>)
  is treated as missing because it matches the input missing value specified by
  <tt>-m 1e9</tt>.

Finally, let's change every second value to 0�K:

$ echo 0 | text2nc -h -u degK vec.nc 'v[1::2]'
$ nc2text -f '%0.1f' vec.nc v
15.0 -273.1 30.2 -273.1 50.0 -273.1 0.0 -273.1

Follow Unidata

Unidata

            Unidata is s a member of the
            UCAR Community Programs,
            managed by the
            University Corporation for Atmospheric Research,
            and funded by the
            National Science Foundation.

            Read Unidata's Participation Policy.

                ©
                   UCAR
                Privacy Policy
                Terms of Use

Contact Unidata

            For support: support@unidata.ucar.edu

            By postal mail or in person

            About this website: plaza@unidata.ucar.edu

            By telephone: 303.497.8643

Welcome to Unidata

            Learn more about who we are and what we do...


text:
#include "ReplayMerge.h"

using namespace aeron::archive::client;

ReplayMerge::ReplayMerge(
    std::shared_ptr<Subscription> subscription,
    std::shared_ptr<AeronArchive> archive,
    const std::string& replayChannel,
    const std::string& replayDestination,
    const std::string& liveDestination,
    std::int64_t recordingId,
    std::int64_t startPosition) :
    m_subscription(std::move(subscription)),
    m_archive(std::move(archive)),
    m_replayChannel(replayChannel),
    m_replayDestination(replayDestination),
    m_liveDestination(liveDestination),
    m_recordingId(recordingId),
    m_startPosition(startPosition),
    m_liveAddThreshold(REPLAY_MERGE_LIVE_ADD_THRESHOLD),
    m_replayRemoveThreshold(REPLAY_MERGE_REPLAY_REMOVE_THRESHOLD)
{
    std::shared_ptr<ChannelUri> subscriptionChannelUri = ChannelUri::parse(m_subscription->channel());

    if (subscriptionChannelUri->get(MDC_CONTROL_MODE_PARAM_NAME) != MDC_CONTROL_MODE_MANUAL)
    {
        throw util::IllegalArgumentException("subscription channel must be manual control mode: mode=" +
            subscriptionChannelUri->get(MDC_CONTROL_MODE_PARAM_NAME), SOURCEINFO);
    }

    m_subscription->addDestination(m_replayDestination);
}

ReplayMerge::~ReplayMerge()
{
    if (State::CLOSED == m_state)
    {
        if (m_isReplayActive)
        {
            m_isReplayActive = false;
            m_archive->stopReplay(m_replaySessionId);
        }

        if (State::MERGED != m_state)
        {
            m_subscription->removeDestination(m_replayDestination);
        }

        state(State::CLOSED);
    }
}

int ReplayMerge::awaitInitialRecordingPosition()
{
    int workCount = 0;

    if (aeron::NULL_VALUE == m_activeCorrelationId)
    {
        const std::int64_t correlationId = m_archive->context().aeron()->nextCorrelationId();

        if (m_archive->archiveProxy().getRecordingPosition(m_recordingId, correlationId, m_archive->controlSessionId()))
        {
            m_activeCorrelationId = correlationId;
            workCount += 1;
        }
    }
    else if (pollForResponse(*m_archive, m_activeCorrelationId))
    {
        m_nextTargetPosition = m_archive->controlResponsePoller().relevantId();
        if (NULL_POSITION == m_nextTargetPosition)
        {
            const std::int64_t correlationId = m_archive->context().aeron()->nextCorrelationId();

            if (m_archive->archiveProxy().getStopPosition(m_recordingId, correlationId, m_archive->controlSessionId()))
            {
                m_activeCorrelationId = correlationId;
                workCount += 1;
            }
        }
        else
        {
            m_initialMaxPosition = m_nextTargetPosition;
            m_activeCorrelationId = aeron::NULL_VALUE;
            state(State::AWAIT_REPLAY);
        }

        workCount += 1;
    }

    return workCount;
}

int ReplayMerge::awaitReplay()
{
    int workCount = 0;

    if (aeron::NULL_VALUE == m_activeCorrelationId)
    {
        const std::int64_t correlationId = m_archive->context().aeron()->nextCorrelationId();

        if (m_archive->archiveProxy().replay(
            m_recordingId,
            m_startPosition,
            std::numeric_limits<std::int64_t>::max(),
            m_replayChannel,
            m_subscription->streamId(),
            correlationId,
            m_archive->controlSessionId()))
        {
            m_activeCorrelationId = correlationId;
            workCount += 1;
        }
    }
    else if (pollForResponse(*m_archive, m_activeCorrelationId))
    {
        m_isReplayActive = true;
        m_replaySessionId = m_archive->controlResponsePoller().relevantId();
        m_activeCorrelationId = aeron::NULL_VALUE;
        state(State::AWAIT_CATCH_UP);
        workCount += 1;
    }

    return workCount;
}

int ReplayMerge::awaitCatchUp()
{
    int workCount = 0;

    if (nullptr == m_image && m_subscription->isConnected())
    {
        m_image = m_subscription->imageBySessionId(static_cast<std::int32_t>(m_replaySessionId));
    }

    if (nullptr != m_image && m_image->position() >= m_nextTargetPosition)
    {
        m_activeCorrelationId = aeron::NULL_VALUE;
        state(State::AWAIT_CURRENT_RECORDING_POSITION);
        workCount += 1;
    }

    return workCount;
}

int ReplayMerge::awaitUpdatedRecordingPosition()
{
    int workCount = 0;

    if (aeron::NULL_VALUE == m_activeCorrelationId)
    {
        const std::int64_t correlationId = m_archive->context().aeron()->nextCorrelationId();

        if (m_archive->archiveProxy().getRecordingPosition(m_recordingId, correlationId, m_archive->controlSessionId()))
        {
            m_activeCorrelationId = correlationId;
            workCount += 1;
        }
    }
    else if (pollForResponse(*m_archive, m_activeCorrelationId))
    {
        m_nextTargetPosition = m_archive->controlResponsePoller().relevantId();
        if (NULL_POSITION == m_nextTargetPosition)
        {
            const std::int64_t correlationId = m_archive->context().aeron()->nextCorrelationId();

            if (m_archive->archiveProxy().getRecordingPosition(
                m_recordingId, correlationId, m_archive->controlSessionId()))
            {
                m_activeCorrelationId = correlationId;
            }
        }
        else
        {
            State nextState = State::AWAIT_CATCH_UP;

            if (nullptr != m_image)
            {
                const std::int64_t position = m_image->position();

                if (shouldAddLiveDestination(position))
                {
                    m_subscription->addDestination(m_liveDestination);
                    m_isLiveAdded = true;
                }
                else if (shouldStopAndRemoveReplay(position))
                {
                    nextState = State::AWAIT_STOP_REPLAY;
                }
            }

            m_activeCorrelationId = aeron::NULL_VALUE;
            state(nextState);
        }

        workCount += 1;
    }

    return workCount;
}

int ReplayMerge::awaitStopReplay()
{
    int workCount = 0;

    if (aeron::NULL_VALUE == m_activeCorrelationId)
    {
        const std::int64_t correlationId = m_archive->context().aeron()->nextCorrelationId();

        if (m_archive->archiveProxy().stopReplay(m_replaySessionId, correlationId, m_archive->controlSessionId()))
        {
            m_activeCorrelationId = correlationId;
            workCount += 1;
        }
    }
    else if (pollForResponse(*m_archive, m_activeCorrelationId))
    {
        m_isReplayActive = false;
        m_replaySessionId = aeron::NULL_VALUE;
        m_activeCorrelationId = aeron::NULL_VALUE;
        m_subscription->removeDestination(m_replayDestination);
        state(State::MERGED);
        workCount += 1;
    }

    return workCount;
}

bool ReplayMerge::pollForResponse(AeronArchive& archive, std::int64_t correlationId)
{
    ControlResponsePoller& poller = archive.controlResponsePoller();

    if (poller.poll() > 0 && poller.isPollComplete())
    {
        if (poller.controlSessionId() == archive.controlSessionId() && poller.correlationId() == correlationId)
        {
            if (poller.isCodeError())
            {
                throw ArchiveException(static_cast<std::int32_t>(poller.relevantId()),
                    "archive response for correlationId=" + std::to_string(correlationId) +
                    ", errorL " + poller.errorMessage(), SOURCEINFO);
            }

            return true;
        }
    }

    return false;
}

redpajama_set_name: RedPajamaGithub


text:
layout: post
title:  "Wrathful Smite"
date:   2014-08-24
sources: [PHB.289]
tags: [paladin, level1, bonus, concentration, evocation]
subtags: [warlock: hexblade]
---

**1st-level evocation**

**Casting Time**: 1 bonus action

**Range**: Self

**Components**: V

**Duration**: Concentration, up to 1 minute

The next time you hit with a melee weapon attack during this spell's duration, your attack deals an extra 1d6 psychic damage. Additionally, if the target is a creature, it must make a Wisdom saving throw or be frightened of you until the spell ends. As an action, the creature can make a Wisdom check against your spell save DC to steel its resolve and end this spell.


text:
2017.08 - version 0.18.0

All
* Updated `SharedAccessSignatureHelper` to accept `Datetime` type as `signedExpiry` or `signedStart` parameter when generating SAS tokens.
* Added samples under samples foder to generate account level or service level SAS tokens with `SharedAccessSignatureHelper`.
* Fixed wrong PHPUnit `@covers` tags in unit and functional test.
* Removed unused imports declarations.

Blob
* Added `BlobRestProxy::listPageBlobRangesDiff` and `BlobRestProxy::listPageBlobRangesDiffAsync` for getting page ranges difference. Refer to https://msdn.microsoft.com/en-us/library/azure/mt736912.aspx for more detailed information.
* Following methods of `MicrosoftAzure\Storage\Blob\BlobRestProxy` now return the x-ms-request-server-encrypted response header. This header is set to true if the contents of the request have been successfully encrypted.
  - `createBlockBlob`, `createPageBlob`, `createAppendBlob`, `createBlobPages`, `createBlobBlock`, `appendBlock`, `commitBlobBlocks` and `setBlobMetadata`.
* Following methods of `MicrosoftAzure\Storage\Blob\BlobRestProxy` now return the x-ms-server-encrypted response header. This header is set to true if the blob data and application metadata are completely encrypted. If the blob is not encrypted, or if only parts of the blob/application metadata are encrypted, this header is set to false.
  - `getBlob` and `getBlobProperties`.

2017.07 - version 0.17.0

All
* REST API version upgraded to 2016-05-31.
* Added support for anonymous read access to containers. User can now call `MicrosoftAzure\Storage\Common\ServiceBuilder::createContainerAnonymousAccess` to create service proxy to access containers/blobs without credential.
* Refined code logic for continuation token. Now continuation token will be null if there are no more instance to be queried/listed.

Blob
* Removed `MicrosoftAzure\Storage\Tests\unit\Blob\Models\BlobContinuationToken`, now use `MicrosoftAzure\Storage\Common\MarkerContinuationToken` instead for better code structure and reuse.
* Added `MicrosoftAzure\Storage\Tests\unit\Blob\BlobRestProxy::blockSize` for user to control block size.

Table
* Deprecated ATOM support for Table service.

Queue
* Removed `MicrosoftAzure\Storage\Tests\unit\Queue\Models\QueueContinuationToken`, now use `MicrosoftAzure\Storage\Common\MarkerContinuationToken` instead for better code structure and reuse.

File
* Removed `MicrosoftAzure\Storage\Tests\unit\File\Models\FileContinuationToken`, now use `MicrosoftAzure\Storage\Common\MarkerContinuationToken` instead for better code structure and reuse.

2017.06 - version 0.16.0

All
* Renamed and moved `MicrosoftAzure\Storage\Blob\Models\PageRange` to `MicrosoftAzure\Storage\Common\Models\Range`.
* Added support for Service Shared Access Signature.
* With File service feature parity to 2015-04-05 and Service Shared Access Signature support in this release, the SDK now have full parity for Blob, Table, Queue and File services to REST API version 2015-04-05.

Table
* Created new types for the following APIs to support specifying accepted content type of response payload. Payload is now by default `application/json;odata=minimalmetadata`.
  - `MicrosoftAzure\Storage\Table\TableRestProxy::createTable` & `MicrosoftAzure\Storage\Table\TableRestProxy::createTableAsync` now uses `MicrosoftAzure\Storage\Table\Models\TableServiceCreateOptions`.
  - `MicrosoftAzure\Storage\Table\TableRestProxy::insertEntity` & `MicrosoftAzure\Storage\Table\TableRestProxy::insertEntityAsync` now uses `MicrosoftAzure\Storage\Table\Models\TableServiceCreateOptions`.
  - `MicrosoftAzure\Storage\Table\TableRestProxy::getTable` & `MicrosoftAzure\Storage\Table\TableRestProxy::getTableAsync` now uses `MicrosoftAzure\Storage\Table\Models\GetTableOptions`.
  - `MicrosoftAzure\Storage\Table\TableRestProxy::getEntity` & `MicrosoftAzure\Storage\Table\TableRestProxy::getEntityAsync` now uses `MicrosoftAzure\Storage\Table\Models\GetEntityOptions`.
* E-Tag can now be null value since when user specified to return minimal/no metadata, E-Tag will not be returned with response.
* When specifying `NO_METADATA` for querying entities, some Edm type, including Edm.Binary, Edm.DateTime and Edm.Guid, could not be determined through the type detection heuristics. For more information, please see [Payload Format for Table Service Operations](https://docs.microsoft.com/en-us/rest/api/storageservices/payload-format-for-table-service-operations).

Queue
* Renamed `MicrosoftAzure\Storage\Queue\Models\MicrosoftAzureQueueMessage` to `MicrosoftAzure\Storage\Queue\Models\QueueMessage`

File
* Added full support for File service, with parity to REST API 2015-04-05.

2017.04 - version 0.15.0

All
* Removed `setRequestOptions` for service options, instead, added `middlewares`, `middlewareStack`, `numberOfConcurrency`, `isStreaming`, `locationMode` and `decodeContent` for user to specify the corresponding options.
* Added `MicrosoftAzure\Storage\Common\Middlewares\RetryMiddleware` to support retry from secondary endpoint. Advice to use this instead of Guzzle's retry middleware for secondary endpoint retry support.
* By setting `$locationMode` in `MicrosoftAzure\Storage\Common\Models\ServiceOptions`, user can perform read operations from secondary endpoint.
* Added support for user to use proxies. If `HTTP_PROXY` is set as a system variable, the proxy specified with it will be used for HTTP connections.
* Removed `MicrosoftAzure\Storage\Common\Models\ServiceProperties::getMetrics` and `MicrosoftAzure\Storage\Common\Models\ServiceProperties::setMetrics`. Added following methods to access hour metrics and minute metrics.
```
MicrosoftAzure\Storage\Common\Models\ServiceProperties::getHourMetrics
MicrosoftAzure\Storage\Common\Models\ServiceProperties::setHourMetrics
MicrosoftAzure\Storage\Common\Models\ServiceProperties::getMinuteMetrics
MicrosoftAzure\Storage\Common\Models\ServiceProperties::setMinuteMetrics
```

Blob
* Access condition feature parity:
  - Single `AccessCondition` has been changed to multiple `AccessCondition` for the options which support access conditions.
  - Added `appendPosition`, `maxBlobSize`, `ifSequenceNumberLessThan`, `ifSequenceNumberEqual` and `ifSequenceNumberLessThanOrEqual` to `AccessCondition` class.
  - Added access conditions support for `getContainerProperties`, `setContainerProperties`, `getContainerMetadata` and `setContainerMetadata`.

* Copy blob feature parity:
  - Added new API `abortCopy`.
  - Added `setIncludeCopy` to `ListBlobsOptions` to support getting copy state information when listing blobs.
  - Added properties and getters/setters for `CopyId` and `CopyStatus` to `CopyBlobResult` class.

* Lease feature parity
  - Added lease support for `getContainerProperties`, `setContainerProperties`, `getContainerMetadata`, `setContainerMetadata` and `deleteContainer`.
  - Renamed `LeaseBlobResult` to `LeaseResult` to support container and blob lease.
  - Added container lease support - passing `null` to `$blob` parameter of the lease related APIs.
  - Added new parameters `$proposedLeaseId` and `$leaseDuration` to `acquireLease` API and changed the `$options` parameter from `AcquireLeaseOptions` to `BlobServiceOptions`.
  - Added the API `changeLease` to support changing lease.
  - Added new parameter `$breakPeriod` to  `breakLease` API and removed the `$leaseId` parameter.
  - Added properties and getters/setters for `LeaseStatus`, `LeaseState` and `LeaseDuration` to `ContainerProperties` class.

* Container/Blob properties feature parity:
  - Added properties and getters/setters for `ContentDisposition`, `LeaseState`, `LeaseDuration` and `CopyState` to `BlobProperties` class.

* Refactored Options class:
  - Exracted `getLeaseId`, `setLeaseId`, `getAccessConditions` and `setAccessConditions` to the base options class `BlobServiceOptions`.
  - Refactored the `CreateBlobOptions`, `CommitBlobBlocksOptions` class to remove duplicate options and standardize the content settings related properties like `ContentType`, `ContentMD5`, `ContentEncoding`, `ContentLanguage`, `CacheControl` and `ContentDisposition`.

* Blob service properties feature parity:
  - Added `getDefaultServiceVersion`, `setDefaultServiceVersion`, `getMinuteMetrics` and `setMinuteMetrics` to `ServiceProperties` class.

* Changed the return type of API `commitBlobBlocks` from `void` to `PutBlobResult`.
* Removed the useless API `ctrCrypt` from `Utilities` class.
* Added `getServiceStats` and `getServiceStatsAsync` for user to request service statistics from the server's secondary endpoint.

Table
* Removed `MicrosoftAzure\Storage\Table\Models\BatchError`. When batch operation fails, exception is thrown immediately instead.
* Added `getServiceStats` and `getServiceStatsAsync` for user to request service statistics from the server's secondary endpoint.

Queue
* Added `getServiceStats` and `getServiceStatsAsync` for user to request service statistics from the server's secondary endpoint.

2017.04 - version 0.14.0

ALL
* Improved the documentation.
* Restructured the classes based on their intended functionality and visiblity. The changes includes:
  - `MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException` was moved to `MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException`
  - `MicrosoftAzure\Storage\Common\ServiceException` was moved to `MicrosoftAzure\Storage\Exceptions\ServiceException`
  - `MicrosoftAzure\Storage\Common\Internal\HttpFormatter` was moved to `MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter`
  - `MicrosoftAzure\Storage\Common\ServiceOptionsBase` was moved to `MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase`
  - `MicrosoftAzure\Storage\Common\Internal\Logger` was moved to `MicrosoftAzure\Storage\Common\Logger`
  - `MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware` was moved to `MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware`
  - `MicrosoftAzure\Storage\Common\Internal\IMiddleware` was moved to `MicrosoftAzure\Storage\Common\Middlewares\IMiddleware`
  - `MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase` was moved to `MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase`
  - `MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory` was moved to `MicrosoftAzure\Storage\Common\Middlewares\RetryMiddlewareFactory`
* Added Cross-Origin Resource Sharing (CORS) support. Now setting service properties can set CORS rules at the same time.
* Added support for account-level Shared Access Signature generation.
* Resolved an error reported from some IDEs about the phpcs.xml.
* Fixed multiple test issues.

Blob
* Added API `createPageBlobFromContent` to support creating page blob directly from contents which includes local file, stream, etc...
* Added support for append blob.
* Added support for Container ACL.

Queue
* Added support for Queue ACL.

Table
* Added support for Table ACL.
* Fixed an issue that user could not set entity type to be double and integer as a value for PHP 7

2017.02 - version 0.13.0

ALL
* The `ServiceException` now provides more detailed information about the request ID and date parsed from the error response.
* Changed the setters in the following class from public to protected to avoid possible misuse of the data structure.
`MicrosoftAzure\Storage\Common\Models\GetServicePropertiesResult`
* Removed version tags in each of the files.
* Added support for the SDK to access Azure Storage Emulator.
* Introduced full support for middlewares. The usage manual can be found in [README.md](README.md).
* Turned on the verification of SSL certificate issuer in the client options.

Blob
* Applied a more robust fix for the issue where `createBlockBlob` would fail for some files with size larger than 1MB and smaller than 32MB.
* Changed the setters in the following classes from public to protected to avoid possible misuse of the data structure.
  ```
  MicrosoftAzure\Storage\Blob\Models\BreakLeaseResult
  MicrosoftAzure\Storage\Blob\Models\CopyBlobResult
  MicrosoftAzure\Storage\Blob\Models\CreateBlobPagesResult
  MicrosoftAzure\Storage\Blob\Models\CreateBlobSnapshotResult
  MicrosoftAzure\Storage\Blob\Models\GetBlobMetadataResult
  MicrosoftAzure\Storage\Blob\Models\GetBlobPropertiesResult
  MicrosoftAzure\Storage\Blob\Models\GetBlobResult
  MicrosoftAzure\Storage\Blob\Models\GetContainerACLResult
  MicrosoftAzure\Storage\Blob\Models\GetContainerPropertiesResult
  MicrosoftAzure\Storage\Blob\Models\LeaseBlobResult
  MicrosoftAzure\Storage\Blob\Models\ListBlobBlocksResult
  MicrosoftAzure\Storage\Blob\Models\ListBlobsResult
  MicrosoftAzure\Storage\Blob\Models\ListPageBlobRangesResult
  MicrosoftAzure\Storage\Blob\Models\PutBlobResult
  MicrosoftAzure\Storage\Blob\Models\PutBlockResult
  MicrosoftAzure\Storage\Blob\Models\SetBlobMetadataResult
  MicrosoftAzure\Storage\Blob\Models\SetBlobPropertiesResult
  ```

Table
* Changed the setters in the following classes from public to protected to avoid possible misuse of the data structure.
  ```
  MicrosoftAzure\Storage\Table\Models\BatchResult
  MicrosoftAzure\Storage\Table\Models\GetEntityResult
  MicrosoftAzure\Storage\Table\Models\GetTableResult
  MicrosoftAzure\Storage\Table\Models\InsertEntityResult
  MicrosoftAzure\Storage\Table\Models\QueryEntitiesResult
  MicrosoftAzure\Storage\Table\Models\QueryTablesResult
  MicrosoftAzure\Storage\Table\Models\UpdateEntityResult
  ```

Queue
* Changed the setters in the following classes from public to protected to avoid possible misuse of the data structure.
  ```
  MicrosoftAzure\Storage\Queue\Models\GetQueueMetadataResult
  MicrosoftAzure\Storage\Queue\Models\ListMessagesResult
  MicrosoftAzure\Storage\Queue\Models\ListQueuesResult
  MicrosoftAzure\Storage\Queue\Models\PeekMessagesResult
  MicrosoftAzure\Storage\Queue\Models\UpdateMessageResult
  ```

2017.01 - version 0.12.1
Blob
* Fixed an issue where `createBlockBlob` would fail for some files with size larger than 1MB and smaller than 32MB.

2017.01 - version 0.12.0

ALL
* Applied type hinting for the project. The rules are listed below:
    * For class arguments: `ClassName $arguments`
    * For array arguments: `array $arguments`
    * For nullable arguments: `ClassName $argument = null`
    * Try to avoid `mixed` type.
    * Use unions for nullable types. e.g. `ClassName|null`.
    * Use `ClassName[]` instead of array, if the type of array is determined.
* Added support for Guzzle async programming model for all APIs.
* Added support for SAS authentication.
Blob
* Changed the return value of following APIs to be more reasonable.
    ```
    createPageBlob
    createBlockBlob
    createBlobBlock
    renewLease
    acquireLease
    ```
* Merged `StorageAuthScheme` into `SharedKeyAuthScheme` and `TableSharedKeyLiteAuthScheme` now inherits `SharedKeyAuthScheme`. This is because Azure Storage now supports Shared Key authentication and SAS authentication so the name `StorageAuthScheme` was not representative anymore.
* Fixed an issue where the newest Guzzle failed to validate the path passed in when `withPath()` is called.

2016.11 - version 0.11.0

ALL
* Fix error string when an error occurs while parsing a connection string and is passed to _createException in `MicrosoftAzure\Storage\Common\Internal\ConnectionStringParser`.
* Added support to create Guzzle's customizable retry middleware to handle the request after the response is received. Also added a default retry policy in case a retry policy is not specified.
* Fixed a bug in unit test where getting properties from service failed to match the expected result due to previous settings have not yet taken effect.
* Fixed some coding style issue. This work will be continued in the following serveral releases, and strictly follows PSR-2 coding style.
* Updated the documentation of `setMetadata`, now in the comments of the following methods `$metadata` is an array instead of a string.
```
MicrosoftAzure\Storage\Blob\Models\Blob.setMetadata
MicrosoftAzure\Storage\Blob\Models\CommitBlobBlocksOptions.setMetadata
MicrosoftAzure\Storage\Blob\Models\GetContainerPropertiesResult.setMetadata
MicrosoftAzure\Storage\Blob\Models\GetBlobResult.setMetadata
MicrosoftAzure\Storage\Blob\Models\GetBlobPropertiesResult.setMetadata
MicrosoftAzure\Storage\Blob\Models\GetBlobMetadataResult.setMetadata
MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions.setMetadata
MicrosoftAzure\Storage\Blob\Models\CreateBlobSnapshotOptions.setMetadata
MicrosoftAzure\Storage\Blob\Models\CreateBlobOptions.setMetadata
MicrosoftAzure\Storage\Blob\Models\CopyBlobOptions.setMetadata
MicrosoftAzure\Storage\Blob\Models\Container.setMetadata
MicrosoftAzure\Storage\Queue\Models\CreateQueueOptions.setMetadata
MicrosoftAzure\Storage\Queue\Models\GetQueueMetadataResult.setMetadata
MicrosoftAzure\Storage\Queue\Models\Queue.setMetadata
```
* Removed test code from composer package.
* `StorageAuthScheme::computeCanonicalizedResource` assumes that the query parameters are already grouped. That is, multi-value query parameters must be assembled using `ServiceRestProxy::groupQueryValues`. This fixes an issue with other single-value query parameters that might contain the separator character in the value.

Blob
* Added support for user to upload large files with minimum memory usage.
* Added concurrent upload for Block Blob.
* Added `MicrosoftAzure\Storage\Blob.saveBlobToFile` for user to download a blob into a file.

2016.08 - version 0.10.2

ALL
* Allow passing an array of options to a service. Currently only Guzzle options are supported via the `http` parameter.

2016.05 - version 0.10.1

Blob
* Fixed the issue that blobs upload with size multiple of 4194304 bytes and larger than 33554432 bytes.
* Fixed the issue that extra / is appended in blob URL.

2016.04 - version 0.10.0

ALL
* Separated Azure Storage APIs in Azure-SDK-for-PHP to establish an independent release cycle.
* Remove all pear dependencies: HTTP_Request2, Mail_mime, and Mail_mimeDecode. Use Guzzle as underlying http client library.
* Update storage REST API version to 2015-04-05.
* Change root namespace from "WindowsAzure" to "MicrosoftAzure/Storage".
* When set metadata operations contains invalid characters, it throws a ServiceException with 400 bad request error instead of Http_Request2_LogicException.

Blob
* Fixed the issue that upload large block blob fails. (https://github.com/Azure/azure-sdk-for-php/pull/757)
* MicrosoftAzure\Storage\Blob\Models\Blocks.setBlockId now requires a base64 encoded string.

Table
* MicrosoftAzure\Storage\Table\Models\Property.getEdmType now returns EdmType::STRING instead of null if the property data type is not set in server.


text:
#include "DlgSystem.h"
#include "DlgLink.h"
#include "DlgNodePhrase.h"
#include <Events/EventManager.h>

namespace Story
{
ImplementRTTI(Story::CDlgNodeAnswers, Story::CDlgNode);
ImplementFactory(Story::CDlgNodeAnswers);

void CDlgNodeAnswers::OnEnter(CActiveDlg& Dlg)
{
	DlgSys->SayPhrase(SpeakerEntity, Phrase, Dlg);
}
//---------------------------------------------------------------------

CDlgNode* CDlgNodeAnswers::Trigger(CActiveDlg& Dlg)
{
#ifdef _DEBUG
	n_assert2(DlgSys->IsDialogueForeground(Dlg) && Dlg.PlrSpeaker.IsValid(),
		"Answer node can be used only in a foreground dialogue with player");
#endif

	if (Dlg.IsCheckingConditions)
	{
		while (Dlg.LinkIdx < Links.Size())
		{
			EExecStatus Status = Links[Dlg.LinkIdx]->Validate(Dlg);
			if (Status == Success)
			{
				n_assert2(Links[Dlg.LinkIdx]->pTargetNode->IsA(CDlgNodePhrase::RTTI), "Answer dlg node should contain ONLY phrase nodes!");

				Dlg.ValidLinkIndices.Append(Dlg.LinkIdx);

				//???send link index too?
				PParams P = n_new(CParams);
				P->Set(CStrID("Phrase"), (PVOID)((CDlgNodePhrase*)Links[Dlg.LinkIdx]->pTargetNode)->Phrase.Get());
				EventMgr->FireEvent(CStrID("OnDlgAnswerVariantAdded"), P);
			}
			else if (Status == Running) return this;
			Dlg.LinkIdx++;
		}

		EventMgr->FireEvent(CStrID((Dlg.ValidLinkIndices.Size() > 0) ? "OnDlgAnswersAvailable" : "OnDlgEndAvailable"));
		Dlg.IsCheckingConditions = false;
	}

	if (!Dlg.Continued) return this;

	return (Dlg.LinkIdx == Links.Size()) ? NULL : Links[Dlg.LinkIdx]->DoTransition(Dlg);
}
//---------------------------------------------------------------------

} //namespace AI


text:
require 'active_support/core_ext/object/blank'

module ActiveModel

  # == Active Model Presence Validator
  module Validations
    class PresenceValidator < EachValidator
      def validate(record)
        record.errors.add_on_blank(attributes, options)
      end
    end

    module HelperMethods
      # Validates that the specified attributes are not blank (as defined by Object#blank?). Happens by default on save. Example:
      #
      #   class Person < ActiveRecord::Base
      #     validates_presence_of :first_name
      #   end
      #
      # The first_name attribute must be in the object and it cannot be blank.
      #
      # If you want to validate the presence of a boolean field (where the real values are true and false),
      # you will want to use <tt>validates_inclusion_of :field_name, :in => [true, false]</tt>.
      #
      # This is due to the way Object#blank? handles boolean values: <tt>false.blank? # => true</tt>.
      #
      # Configuration options:
      # * <tt>message</tt> - A custom error message (default is: "can't be blank").
      # * <tt>on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>,
      #   <tt>:update</tt>).
      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
      #   occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
      #   The method, proc or string should return or evaluate to a true or false value.
      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
      #   not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
      #   The method, proc or string should return or evaluate to a true or false value.
      #
      def validates_presence_of(*attr_names)
        validates_with PresenceValidator, _merge_attributes(attr_names)
      end
    end
  end
end


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>advmod:tmod</title>
    <link rel="root" href=""/>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="../../css/jquery-ui-redmond.css"/>
    <link rel="stylesheet" type="text/css" href="../../css/style.css"/>
    <link rel="stylesheet" type="text/css" href="../../css/style-vis.css"/>
    <link rel="stylesheet" type="text/css" href="../../css/hint.css"/>

          home

          edit page
          issue tracker

          <gcse:search></gcse:search>

        This page pertains to UD version 2.

            It appears that you have Javascript disabled.
            Please consider enabling Javascript for this page to see the visualizations.

advmod:tmod: temporal adverbial modifier

This semantical subrelation is used to single out those adverbial modifiers that express a temporal reference, usually by means of a particular subclass of words which are marked with AdvType=Tim and conventionally annotated as ADVs.

The kinds of temporal relations expressed (duration, definiteness, and so on) are often readable from the morphological history of the adverbial element (e.g. hodie 'today' is a contraction of the ablative phrase hoc die 'on this day'), but do not appear to be fully standardised (i.e. there is a variety of synchronically non-predictable forms, like semper 'always').

The tmod subrelation is also used for oblique arguments, which usually consist of nominal phrases: since, in Latin, this appears to be a purely formal distinction with regard to adverbial temporal (but also locative) expressions (often derived from nominal forms), the use of tmod aims to capture the fundamental unitarity of such constructions.

Huius iudicium omnem severitatem abhorret , et semper citra medium plectens , ultra medium premiando se figit . \n Of-him judgement all severity abhors , and always on-this-side mean punishing , beyond mean with-rewarding himself fixes .
advcl:tmod(figit,semper)
advcl:tmod(fixes,always)

'His judgements abhor all severity, for he punishes ever on this side the mean, while in rewarding he aims ever beyond the mean.' (Letters, UDante)

advmod:tmod in other languages:

[apu]

[koi]

[kpv]

[la]

[mdf]

[myv]

[ro]

[sms]

© 2014–2021
            Universal Dependencies contributors.
            Site powered by Annodoc and brat
.


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using Umbraco.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Current = Umbraco.Web.Composing.Current;

namespace Umbraco.Web.Models
{
    /// <summary>
    /// A readonly member profile model
    /// </summary>
    [ModelBinder(typeof(ProfileModelBinder))]
    public class ProfileModel : PostRedirectModel
    {

        public static ProfileModel CreateModel()
        {
            var model = new ProfileModel(false);
            return model;
        }

        private ProfileModel(bool doLookup)
        {
            MemberProperties = new List<UmbracoProperty>();
            if (doLookup && Current.UmbracoContext != null)
            {
                var helper = Current.Factory.GetInstance<MembershipHelper>();
                var model = helper.GetCurrentMemberProfileModel();
                MemberProperties = model.MemberProperties;
            }
        }

        [Required]
        [RegularExpression(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
            ErrorMessage = "Please enter a valid e-mail address")]
        public string Email { get; set; }

        /// <summary>
        /// The member's real name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// The member's member type alias
        /// </summary>
        [ReadOnly(true)]
        public string MemberTypeAlias { get; set; }

        [ReadOnly(true)]
        public string UserName { get; set; }

        [ReadOnly(true)]
        public string PasswordQuestion { get; set; }

        [ReadOnly(true)]
        public string Comment { get; set; }

        [ReadOnly(true)]
        public bool IsApproved { get; set; }

        [ReadOnly(true)]
        public bool IsLockedOut { get; set; }

        [ReadOnly(true)]
        public DateTime LastLockoutDate { get; set; }

        [ReadOnly(true)]
        public DateTime CreationDate { get; set; }

        [ReadOnly(true)]
        public DateTime LastLoginDate { get; set; }

        [ReadOnly(true)]
        public DateTime LastActivityDate { get; set; }

        [ReadOnly(true)]
        public DateTime LastPasswordChangedDate { get; set; }

        /// <summary>
        /// The list of member properties
        /// </summary>
        /// <remarks>
        /// Adding items to this list on the front-end will not add properties to the member in the database.
        /// </remarks>
        public List<UmbracoProperty> MemberProperties { get; set; }

        /// <summary>
        /// A custom model binder for MVC because the default ctor performs a lookup!
        /// </summary>
        internal class ProfileModelBinder : DefaultModelBinder
        {
            protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
            {
                return ProfileModel.CreateModel();
            }

        }
    }
}