In the following examples, we make use of:
TOPCAT and Aladin will run a SAMP Hub is none is found, so for the following examples you can either start up one of these applications first, or you can start up the astropy.vo.samp hub. You can start this using the following command:
$ samp_hub
The easiest way to send a VO table to TOPCAT is to make use of the SAMPIntegratedClient class. Once TOPCAT is open, then first instantiate a SAMPIntegratedClient instance and connect to the hub:
>>> from astropy.vo.samp import SAMPIntegratedClient
>>> client = SAMPIntegratedClient()
>>> client.connect()
Next, we have to set up a dictionary that contains details about the table to send. This should include url, which is the URL to the file, and name, which is a human-readable name for the table. The URL can be a local URL (starting with file:///):
>>> params = {}
>>> params["url"] = 'file:///Users/tom/Desktop/aj285677t3_votable.xml'
>>> params["name"] = "Robitaille et al. (2008), Table 3"
Note
To construct a local URL, you can also make use of urlparse as follows:
>>> import urlparse
>>> params["url"] = urlparse.urljoin('file:', os.path.abspath("aj285677t3_votable.xml"))
Now we can set up the message itself. This includes the type of message (here we use table.load.votable which indicates that a VO table should be loaded, and the details of the table that we set above:
>>> message = {}
>>> message["samp.mtype"] = "table.load.votable"
>>> message["samp.params"] = params
Finally, we can broadcast this to all clients that are listening for table.load.votable messages using notify_all():
>>> client.notify_all(message)
The above message will actually be broadcast to all applications connected via SAMP. For example, if we open SAO Ds9 in addition to TOPCAT, and we run the above command, both applications will load the table. We can use the get_registered_clients() method to find all the clients connected to the hub:
>>> client.get_registered_clients()
['hub', 'c1', 'c2']
These IDs don’t mean much, but we can find out more using:
>>> client.get_metadata('c1')
{'author.affiliation': 'Astrophysics Group, Bristol University',
'author.email'<EMAIL_ADDRESS>'author.name': 'Mark Taylor',
'home.page': 'http://www.starlink.ac.uk/topcat/',
'samp.description.text': 'Tool for OPerations on Catalogues And Tables',
'samp.documentation.url': 'http://<IP_ADDRESS>:2525/doc/sun253/index.html',
'samp.icon.url': 'http://<IP_ADDRESS>:2525/doc/images/tc_sok.gif',
'samp.name': 'topcat',
'topcat.version': '4.0-1'}
We can see that c1 is the TOPCAT client. We can now re-send the data, but this time only to TOPCAT, using the notify() method:
>>> client.notify('c1', message)
Once finished, we should make sure we disconnect from the hub:
>>> client.disconnect()
To receive a table from TOPCAT, we have to set up a client that listens for messages from the hub. As before, we instantiate a SAMPIntegratedClient instance and connect to the hub:
>>> from astropy.vo.samp import SAMPIntegratedClient
>>> client = SAMPIntegratedClient()
>>> client.connect()
We now set up a receiver class which will handle any received message. We need to take care to write handlers for both notifications and calls (the difference between the two being that calls expect a reply):
>>> class Receiver(object):
... def __init__(self, client):
... self.client = client
... self.received = False
... def receive_call(self, private_key, sender_id, msg_id, mtype, params, extra):
... self.params = params
... self.received = True
... self.client.reply(msg_id, {"samp.status": "samp.ok", "samp.result": {}})
... def receive_notification(self, private_key, sender_id, mtype, params, extra):
... self.params = params
... self.received = True
and we instantiate it:
>>> r = Receiver(client)
We can now use the bind_receive_call() and bind_receive_notification() methods to tell our receiver to listen to all table.load.votable messages:
>>> client.bind_receive_call("table.load.votable", r.receive_call)
>>> client.bind_receive_notification("table.load.votable", r.receive_notification)
We can now check that the message has not been received yet:
>>> r.received
False
Let’s now broadcast the table from TOPCAT. After a few seconds, we can try and check again if the message has been received:
>>> r.received
True
Success! The table URL should now be available in r.params['url'], so we can do:
>>> from astropy.table import Table
>>> t = Table.read(r.params['url'])
Downloading http://<IP_ADDRESS>:2525/dynamic/4/t12.vot [Done]
>>> t
col1 col2 col3 col4 col5 col6 col7 col8 col9 col10
------------------------- -------- ------- -------- -------- ----- ---- ----- ---- -----
SSTGLMC G000.0046+01.1431 0.0046 1.1432 265.2992 -28.3321 6.67 5.04 6.89 5.22 N
SSTGLMC G000.0106-00.7315 0.0106 -0.7314 267.1274 -29.3063 7.18 6.07 nan 5.17 Y
SSTGLMC G000.0110-01.0237 0.0110 -1.0236 267.4151 -29.4564 8.32 6.30 8.34 6.32 N
...
As before, we should remember to disconnect from the hub once we are done:
>>> client.disconnect()
The following is a full example of a script that can be used to receive and read a table. It includes a loop that waits until the message is received, and reads the table once it has:
import time
from astropy.vo.samp import SAMPIntegratedClient
from astropy.table import Table
# Instantiate the client and connect to the hub
client=SAMPIntegratedClient()
client.connect()
# Set up a receiver class
class Receiver(object):
def __init__(self, client):
self.client = client
self.received = False
def receive_call(self, private_key, sender_id, msg_id, mtype, params, extra):
self.params = params
self.received = True
self.client.reply(msg_id, {"samp.status": "samp.ok", "samp.result": {}})
def receive_notification(self, private_key, sender_id, mtype, params, extra):
self.params = params
self.received = True
# Instantiate the receiver
r = Receiver(client)
# Listen for any instructions to load a table
client.bind_receive_call("table.load.votable", r.receive_call)
client.bind_receive_notification("table.load.votable", r.receive_notification)
# We now run the loop to wait for the message in a try/finally block so that if
# the program is interrupted e.g. by control-C, the client terminates
# gracefully.
try:
# We test every 0.1s to see if the hub has sent a message
while True:
time.sleep(0.1)
if r.received:
t = Table.read(r.params['url'])
break
finally:
client.disconnect()
# Print out table
print t
As for tables, the easiest way to send a FITS image over SAMP is to make use of the SAMPIntegratedClient class. Once Aladin or Ds9 are open, then first instantiate a SAMPIntegratedClient instance and connect to the hub as before:
>>> from astropy.vo.samp import SAMPIntegratedClient
>>> client = SAMPIntegratedClient()
>>> client.connect()
Next, we have to set up a dictionary that contains details about the image to send. This should include url, which is the URL to the file, and name, which is a human-readable name for the table. The URL can be a local URL (starting with file:///):
>>> params = {}
>>> params["url"] = 'file:///Users/tom/Desktop/MSX_E.fits'
>>> params["name"] = "MSX Band E Image of the Galactic Center"
See Sending a table to TOPCAT and Ds9 for an example of how to construct local URLs more easily. Now we can set up the message itself. This includes the type of message (here we use image.load.fits which indicates that a FITS image should be loaded, and the details of the table that we set above:
>>> message = {}
>>> message["samp.mtype"] = "image.load.fits"
>>> message["samp.params"] = params
Finally, we can broadcast this to all clients that are listening for table.load.votable messages:
>>> client.notify_all(message)
As for Sending a table to TOPCAT and Ds9, the notify_all() method will broadcast the image to all listening clients, and as for tables it is possible to instead use the notify() method to send it to a specific client.
Once finished, we should make sure we disconnect from the hub:
>>> client.disconnect()
Receiving images over SAMP is identical to Receiving a table from TOPCAT, with the exception that the message type should be image.load.fits instead of table.load.votable. Once the URL has been received, the FITS image can be opened with:
>>> from astropy.io import fits
>>> fits.open(r.params['url'])


--- layout: default title: Contact Us permalink: /contact/ body_class: contact excerpt: Contact us for help with existing policies, or help issuing a new policy. ---
Phone:
+1-928-214-9750
or toll free
+1-888-723-4617
Fax:
+1-928-213-8476
214 East Birch Avenue
Flagstaff,
Arizona
86001
Hours of Operation:
Monday - Friday, 7:30 a.m. - 6 p.m. MST
Saturday 7 a.m. - 4 p.m. MST


This product is made available subject to acceptance of the EPICS open source license.
pvDataJava is a computer software package for the efficient
storage, access, and communication, of structured data. It is specifically the
Java implementation of pvData, which is one part of the set of related products in the EPICS
V4 control system programming environment:
relatedDocumentsV4.html
This is the 29-March-2017 version of the Java implementation of pvData.
RELEASE_NOTES.md provides changes since the last release. TODO.md describes things to do before the next release.
pvData is one of a set of related projects. It describes and implements data that the other projects support. Thus it is not useful by itself but understanding pvData is required in order to understand the other projects. The reader should also become familiar with project pvAccess, which is located via the same sourceforge site as this project.
developerGuide briefly describes a set of application programming interfaces (APIs) for EPICS V4. It should be read before reading this manual.
The Java and C++ implementation of pvData implement the same data model but differ in implementation because of the differences between Java and C++.
pvData is one of a set of related packages in the EPICS V4 core software. It describes and implements the data management system to which the the other projects interface.
pvData (Process Variable Data) defines and implements an efficient way to store, access, and communicate memory resident data structures.
This section gives a brief description of the pvData introspection and data interfaces. In this section the methods are shown but not described. See org.epics.pvdata.pv below for a description of each method.
The following are the type definitions:
enum Type { scalar, scalarArray, structure, structureArray, union_t, unionArray; }
where
ScalarType
s.ScalarType
.enum ScalarType { pvBoolean, pvByte,pvShort,pvInt,pvLong, pvUByte,pvUShort,pvUInt,pvULong, pvFloat,pvDouble, pvString; // The following are convenience methods public boolean isInteger(); public boolean isUInteger(); public boolean isNumeric(); public boolean isPrimitive(); public static ScalarType getScalarType(String type); public String toString(); }
where
NOTE: Java does not support unsigned integers so the Java implementation of each unsigned type is implemented as the corresponding signed type. The only exception is the Convert facility. When it performs a widening operation, e.g. from ubyte to short, it performs the correct conversion.
Field
is the base introspection interface. It has only an ID and a type.
interface Field extends Serializable { String getId(); Type getType(); void toString(StringBuilder buf); void toString(StringBuilder buf,int indentLevel); String toString(); } interface Scalar extends Field { ScalarType getScalarType(); } interface ScalarArray extends Field { ScalarType getElementType(); } interface Structure extends Field { Field getField(String fieldName); Field getField(int fieldIndex); <T extends Field> T getField(Class<T> c, String fieldName); <T extends Field> T getField(Class<T> c, int fieldIndex); Field[] getFields(); String[] getFieldNames(); int getFieldIndex(String fieldName); String getFieldName(int fieldIndex); } interface StructureArray extends Field { Structure getStructure(); } public interface Union extends Field{ public static final String DEFAULT_ID = "union"; public static final String ANY_ID = "any"; Field getField(String fieldName); Field getField(int fieldIndex); <T extends Field> T getField(Class<T> c, String fieldName); <T extends Field> T getField(Class<T> c, int fieldIndex); Field[] getFields(); String[] getFieldNames(); int getFieldIndex(String fieldName); String getFieldName(int fieldIndex); boolean isVariant(); } public interface UnionArray extends Field{ Union getUnion(); }
The introspection interfaces provide access to immutable objects. This allows introspection interfaces to be freely shared between data objects. For example the introspection interface for a timeStamp, which is a structure containing two fields, can be shared by every record that has a time stamp.
PVField
is the base interface for a data field:
interface PVField extends Serializable { String getFieldName(); String getFullName(); int getFieldOffset(); int getNextFieldOffset(); int getNumberFields(); boolean isImmutable(); void setImmutable(); Field getField(); PVStructure getParent(); void postPut(); void setPostHandler(PostHandler postHandler); void toString(StringBuilder buf); void toString(StringBuilder buf,int indentLevel); String toString(); // The following should go away. PVAuxInfo getPVAuxInfo(); }
Each scalar type has an associated data interface: PVBoolean
,
PVByte
, PVShort
, PVInt
, PVLong
,
PVUByte
, PVUShort
, PVUInt
, PVULong
,
PVFloat
, PVDouble
and PVString
. Each has a get
and a
put
method. For example:
interface PVDouble extends PVScalar{ double get(); void put(double value); }
PVArray
is the base class for arrays.
interface PVArray extends PVField, SerializableArray { Array getArray(); int getLength(); void setLength(int length); int getCapacity(); void setCapacity(int length); boolean isCapacityMutable(); void setCapacityMutable(boolean isMutable); }
PVScalarArray
is the base class for scalar arrays.
interface PVScalarArray extends PVArray { ScalarArray getScalarArray(); }
For each scalar type an associated array data interface is defined. Each has
a get
and put
method. For example:
public class DoubleArrayData { public double[] data; public int offset; } interface PVDoubleArray extends PVArray { int get(int offset, int len, DoubleArrayData data); int put(int offset,int len, double[] from, int fromOffset); void shareData(double[] from); }
PVStructureArray
is the interface for an array of structures where each element
has the same introspection interface.
public class StructureArrayData { public PVStructure[] data; public int offset; } interface PVStructureArray extends PVArray{ StructureArray getStructureArray(); int get(int offset, int length, StructureArrayData data); int put(int offset,int length, PVStructure[] from, int fromOffset); void shareData(PVStructure[] from); }
PVStructure
is the data interface for a structure.
interface PVStructure extends PVField , BitSetSerializable{ Structure getStructure(); PVField[] getPVFields(); PVField getSubField(String fieldName); PVField getSubField(int fieldOffset); <T extends PVField> T getSubField(Class<T> c, String fieldName); <T extends PVField> T getSubField(Class<T> c, int fieldOffset); // The following are convenience methods // Note that they are no longer needed because of above generic methods PVBoolean getBooleanField(String fieldName); PVByte getByteField(String fieldName); PVShort getShortField(String fieldName); PVInt getIntField(String fieldName); PVLong getLongField(String fieldName); PVFloat getFloatField(String fieldName); PVDouble getDoubleField(String fieldName); PVString getStringField(String fieldName); PVScalarArray getScalarArrayField(String fieldName); PVStructureArray getStructureArrayField(String fieldName); PVStructure getStructureField(String fieldName); PVArray getArrayField(String fieldName,ScalarType elementType); PVUnion getUnionField(String fieldName); PVUnionArray getUnionArrayField(String fieldName); public boolean checkValid(); }
The following interface creates introspection instances:
public interface FieldCreate { FieldBuilder createFieldBuilder(); Scalar createScalar(ScalarType scalarType); BoundedString createBoundedString(int maxLength); ScalarArray createScalarArray(ScalarType elementType); ScalarArray createFixedScalarArray(ScalarType elementType, int size); ScalarArray createBoundedScalarArray(ScalarType elementType, int bound); StructureArray createStructureArray(Structure elementStructure); UnionArray createUnionArray(Union elementUnion); UnionArray createVariantUnionArray(); Structure createStructure(String[] fieldNames, Field[] field); Structure createStructure(String id,String[] fieldNames, Field[] field); Structure appendField(Structure structure,String fieldName, Field field); Structure appendFields(Structure structure,String[] fieldNames, Field[] fields); Structure createStructure(Structure structToClone); Union createVariantUnion(); Union createUnion(String[] fieldNames, Field[] fields); Union createUnion(String id, String[] fieldNames, Field[] fields); Field deserialize(ByteBuffer buffer, DeserializableControl control); }
The following is a convenience class for creating introspection objects:
public interface FieldBuilder { public FieldBuilder setId(String id); public FieldBuilder add(String name, ScalarType scalarType); public FieldBuilder addBoundedString(String name, int maxLength); public FieldBuilder add(String name, Field field); public FieldBuilder addArray(String name, ScalarType scalarType); public FieldBuilder addFixedArray(String name, ScalarType scalarType, int size); public FieldBuilder addBoundedArray(String name, ScalarType scalarType, int bound); public FieldBuilder addArray(String name, Field element); public Structure createStructure(); public Union createUnion(); FieldBuilder addNestedStructure(String name); FieldBuilder addNestedUnion(String name); FieldBuilder addNestedStructureArray(String name); FieldBuilder addNestedUnionArray(String name); FieldBuilder endNested(); }
The following interface creates data instances:
public interface PVDataCreate { PVField createPVField(Field field); PVField createPVField(PVField fieldToClone); PVScalar createPVScalar(Scalar scalar); PVScalar createPVScalar(ScalarType fieldType); PVScalar createPVScalar(PVScalar scalarToClone); <T extends PVScalar, TA extends PVScalarArray> T createPVScalar( PVScalarType<T, TA> scalarType); PVScalarArray createPVScalarArray(ScalarArray array); PVScalarArray createPVScalarArray(ScalarType elementType); PVScalarArray createPVScalarArray(PVScalarArray arrayToClone; <T extends PVScalar, TA extends PVScalarArray> TA createPVScalarArray( PVScalarType<T, TA> elementType); PVStructureArray createPVStructureArray(StructureArray structureArray); PVUnionArray createPVUnionArray(UnionArray unionArray); PVUnionArray createPVVariantUnionArray(); PVStructure createPVStructure(Structure structure); PVStructure createPVStructure(String[] fieldNames,Field[] fields); PVStructure createPVStructure(PVStructure structToClone); PVUnion createPVUnion(Union union); PVUnion createPVVariantUnion(); PVUnion createPVUnion(PVUnion unionToClone); PVStructureArray createPVStructureArray(Structure structure); PVUnionArray createPVUnionArray(Union union); PVField[] flattenPVStructure(PVStructure pvStructure); }
An interface named Convert
provides all reasonable conversions to/from
pvData.
The convert utility is also used to implement the toString
methods of PVField
.
See org.epics.pvdata.pv.Convert
for details.
This document describes everything via Java definitions. The initial implementation is in Java but the functionality is also implemented in C++ (See pvDataCPP for details).
pvData is distributed as a sourceforge mercurial project named pvDataJava. It consists of the following Java packages:
The Java enum, interface, and class definitions that define pvData. This section provides a complete definition of what pvData is.
Provides everything required for creating pvData. It provides the following factories:
Although pvDataFactory can provide the implementation for all supported data types, often it is desirable to provide other implementations. To make it easy to create alternate implementations a set of abstract and base classes are supplied.
Provides a way to associated properties with a field.
The basic idea is to associate properties with any field named "value". All the fields in the structure that contains the value field are considered properties of value with the field name being the property name. See that package overview for details.
This package also provides support for "well known" field definitions like timeStamp, alarm, display,etc. Code that uses pvData can be simplified by using this support.
This package provides support that is used by pvData factories and might also be useful to software that uses pvData.
Provides the ability to monitor changes to an arbitrary subset of the fields in a record.
This package has the complete set of enum, interface, and class definitions that describe pvData. The implementation is provided in package org.epics.pvdata.factory.
A PVStructure
is a field that contains an array of subfields. Each field has
code for accessing the field. The interface for each field is PVField
or an
interface that extends PVField
. Each field also has an introspection interface,
which is Field
or an extension of Field
. This package overview describes the
complete set of data and introspection interfaces for pvData.
This package also describes an interface Convert, which provides a rich set of methods for converting and copying data between field.
The interface FieldCreate
creates the introspection interfaces. The
interface PVDataCreate
creates the PVField
interfaces. Between them they
provide the ability to create every type of Field
and PVField
, i.e. they
provide a complete implementation of pvData. It is also possible for other code
to provide implementations.
The interface StandardField
provides introspection objects for standard fields.
The interface StandardPVField
provides data objects for standard fields.
The interface StatusCreate
and class Status
provide status objects to pass between source
modules.
Given the introspection object it is possible to introspect a field without requiring access to data. The reflection and data interfaces are separate because the data may not be available. For example when a pvAccess client connects to a PV, the client library can obtain the reflection information without obtaining any data. Only when a client issues an I/O request will data be available. This separation is especially important for arrays and structures so that a client can discover the type without requiring that a large array or structure be transported over the network.
The types are defined by the Java definitions:
enum Type { scalar, scalarArray, structure, structureArray, union, unionArrray; } enum ScalarType { pvBoolean, pvByte, pvShort, pvInt, pvLong, pvUByte, pvUShort, pvUInt, pvULong, pvFloat,pvDouble, pvString; //Convenience methods public boolean isInteger(); // pvByte,...,pvULong public boolean isUInteger(); // pvUByte,...,pvULong public boolean isNumeric(); // pvByte,...pvDouble public boolean isPrimitive(); // pvBoolean,...pvDouble public static ScalarType getScalarType(String type); public String toString(); }
The following interfaces are called by pvAccess for transporting data over the network. The abstract and base classes ensure that these methods are properly implemented.
interface Serializable { void serialize(ByteBuffer buffer,SerializableControl flusher); void deserialize(ByteBuffer buffer,DeserializableControl control); }where
interface SerializableControl { void flushSerializeBuffer(); void ensureBuffer(int size); void alignBuffer(int alignment); void cachedSerialize(Field field, ByteBuffer buffer) }where
Field
instance via cache.interface DeserializableControl { void ensureData(int size); void alignData(int alignment); Field cachedDeserialize(ByteBuffer buffer) }where
Field
instance via cache.interface SerializableArray extends Serializable { void serialize(ByteBuffer buffer, SerializableControl flusher, int offset, int count); }where
interface BitSetSerializable { void serialize(ByteBuffer buffer, SerializableControl flusher, BitSet bitSet); void deserialize(ByteBuffer buffer, DeserializableControl control, BitSet bitSet); }where
BitSet
shows the fields to serialize.BitSet
shows the fields to serialize.This section defines the complete set of Java PV reflection interfaces. Reflection consists of the following:
Field
has an ID and a type. It can be converted to a string.
The format is the metadata format
described in the overview.Scalar
has a ScalarType
ScalarArray
has a ScalarType
corresponding to the element typeStructure[]
. Each element has the same Structure
introspection interface. A client can only get
/put
entire PVStructure
elements NOT subfields of array elements.Union
describes which of these
applies and the set of types in the case of a regular union. Union[]
. Each element has the same
Union
introspection interface.FieldCreate
.interface Field extends Serializable { String getID(); Type getType(); void toString(StringBuilder buf)); void toString(StringBuilder buf,int indentLevel); String toString(); }where
interface Scalar extends Field { ScalarType getScalarType(); }where
interface ScalarArray extends Field{ ScalarType getElementType(); }where
ScalarType
for each array element.interface Structure extends Field{ Field getField(String fieldName); Field getField(int fieldIndex); <T extends Field> T getField(Class<T> c, String fieldName); <T extends Field> T getField(Class<T> c, int fieldIndex); Field[] getFields(); String[] getFieldNames(); int getFieldIndex(String fieldName); String getFieldName(int fieldIndex); }where
Field
for the index.interface StructureArray extends Field{ Structure getStructure(); }where
public interface Union extends Field{ public static final String DEFAULT_ID = "union"; public static final String ANY_ID = "any"; Field getField(String fieldName); Field getField(int fieldIndex); <T extends Field> T getField(Class<T> c, String fieldName); <T extends Field> T getField(Class<T> c, int fieldIndex); Field[] getFields(); String[] getFieldNames(); int getFieldIndex(String fieldName); String getFieldName(int fieldIndex); boolean isVariant(); }where
public interface UnionArray extends Field{ Union getUnion(); }where
Syntax for fieldName and ID.
A fieldName must begin with a letter and must be a sequence of letters and digits. A letter is defined as 'A'-'Z', 'a'-'z','_', or any Unicode character that denotes a letter in a language. Similarly digits are '0'-'9' and any Unicode character that denotes a digit in a language. Note that this is the same as the Java syntax for variable names.
The syntax for ID is the same except the '.' is also allowed after the initial letter.
public interface FieldCreate { FieldBuilder createFieldBuilder(); Scalar createScalar(ScalarType scalarType); BoundedString createBoundedString(int maxLength); ScalarArray createScalarArray(ScalarType elementType); ScalarArray createFixedScalarArray(ScalarType elementType, int size); ScalarArray createBoundedScalarArray(ScalarType elementType, int bound); StructureArray createStructureArray(Structure elementStructure); UnionArray createUnionArray(Union elementUnion); UnionArray createVariantUnionArray(); Structure createStructure(String[] fieldNames, Field[] field); Structure createStructure(String id,String[] fieldNames, Field[] field); Structure appendField(Structure structure,String fieldName, Field field); Structure appendFields(Structure structure,String[] fieldNames, Field[] fields); Structure createStructure(Structure structToClone); Union createVariantUnion(); Union createUnion(String[] fieldNames, Field[] fields); Union createUnion(String id, String[] fieldNames, Field[] fields); Field deserialize(ByteBuffer buffer, DeserializableControl control); }where
FieldBuilder
, which is described next.Scalar
with the specified ScalarType
.
Note that the implementation creates a single instance for
each ScalarType
.pvString
that has a bounded size for a string.ScalarArray
with the specified elementType
.
Note that the implementation creates a single instance for
each elementType
.ScalarArray
with the specified elementType
and specifies that size of
element size of any object that has this introspection interface.ScalarArray
with the specified elementType
and specifies that maximum
element size of any object that has this introspection interface.StructureArray
with the specified introspection
interface for each array element.UnionArray
with the specified introspection interface.UnionArray
of variant union elements.Structure
. There are two methods.
The first creates a structure with an empty ID which results in an ID of structure.
FieldBuilder
is a convenience class for creating introspection interfaces.
An example is:
FieldCreate fieldCreate = FieldFactory.getFieldCreate(); Structure s = fieldCreate.createFieldBuilder(). add("double", ScalarType.pvDouble). addNestedStructure("nested"). add("short", ScalarType.pvShort). add("long", ScalarType.pvLong). endNested(). addArray("intArray", ScalarType.pvInt). createStructure(); System.out.println(s);This produces:
structure double double structure nested short short long long int[] intArray
The Java interface is:
public interface FieldBuilder { public FieldBuilder setId(String id); public FieldBuilder add(String name, ScalarType scalarType); public FieldBuilder addBoundedString(String name, int maxLength); public FieldBuilder add(String name, Field field); public FieldBuilder addArray(String name, ScalarType scalarType); public FieldBuilder addFixedArray(String name, ScalarType scalarType, int size); public FieldBuilder addBoundedArray(String name, ScalarType scalarType, int bound); public FieldBuilder addArray(String name, Field element); public Structure createStructure(); public Union createUnion(); FieldBuilder addNestedStructure(String name); FieldBuilder addNestedUnion(String name); FieldBuilder addNestedStructureArray(String name); FieldBuilder addNestedUnionArray(String name); FieldBuilder endNested(); }
createStructure
or createUnion call
.
createStructure
or createUnion
.
There are two forms: one for an existing field and the other for a scalar field.
createStructure
or createUnion
.
There are two forms: one for an existing field and the other for a scalar field.
Note that for an existing field this specifies the element type.
Structure
from the previous add
and addArray
methods.
Union
from the previous add
and addArray
methods.
endNested
.
endNested
.
endNested
.
endNested
.
Status
provides a way to pass status back to client code. It is new and not
currently used by pvData but may be in the future. It is used by code that uses
pvData.
interface Status extends Serializable { public enum StatusType {OK,WARNING,ERROR,FATAL}; StatusType getType(); String getMessage(); String getStackDump(); boolean isOK(); boolean isSuccess(); }where
StatusType
.StatusType.OK
?StatusType
either OK or WARNING?interface StatusCreate { Status getStatusOK(); Status createStatus(StatusType type, String message, Throwable cause); Status deserializeStatus(ByteBuffer buffer, DeserializableControl control); }where
Requester is an interface that allows messages to be given to client code.
An instance of Requester
must be implemented by the client.
The definition is:
enum MessageType {info,warning,error,fatalError} interface Requester { String getRequesterName(); void message(String message, MessageType messageType); }
where
PVField
prepends the full field name
to the message and calls PVRecord.message
. The default implementation
for PVRecord
either displays the message on stdout or stderr or gives
the message to message requesters.This section defines the Java Interfaces for accessing the data within
a top-level PVStructure
.
PVField
is the base interface for accessing data. Every field of a
top-level PVStructure
has a PVField
associated with it.
This includes the top-level structure itself.
interface PVField Serializable { String getFieldName(); String getFullName(); int getFieldOffset(); int getNextFieldOffset(); int getNumberFields(); boolean isImmutable(); void setImmutable(); Field getField(); PVStructure getParent(); void postPut(); void setPostHandler(PostHandler postHandler); void toString(StringBuilder buf); void toString(StringBuilder buf,int indentLevel); String toString(); // The following should go away. PVAuxInfo getPVAuxInfo(); }
where
PVField
field within top-level structure. Every field
within the PVStructure
has a unique offset. The top-level structure has
an offset of 0. The first field within the structure has offset equal to
1. The other offsets are determined by recursively traversing each
structure of the tree. PVStructure
.PostHandler
is registered it is called otherwise no action is
taken.postPut
when a field is changed. However this is not true
for a subField of a PVUnion
, PVUnionArray
, or PVStructureArray
.
If a subField of any of these is changed then the code that is making
the modification must call postPut
for the PVUnion
, PVUnionArray
, or PVStructureArray
field. Note also that it is not a good idea to modify a subfield of a PVUnionArray
or a PVStructureArray
since it violates the idea of Copy On Write for arrays.
postPut
. At most one handler can be set.NOTE: PVAuxInfo should go away.
AuxInfo (Auxiliary Information) is information about a field that is
application specific. It will not be available outside the application that
implements the database. In particular it will not be made available to Channel
Access. It is used by the database itself to override the default
implementation of fields. The JavaIOC used it for attaching support code.
Database Configuration and other tools can use it for configuration
information. Each Field
and each PVField
can have have an arbitrary number of
auxInfos. An auxInfo is a (key,PVScalar
) pair where key is a string.
public interface PVAuxInfo { PVField getPVField(); PVScalar createInfo(String key,ScalarType scalarType); Map<String,PVScalar> getInfos(); PVScalar getInfo(String key); void toString(StringBuilder buf); void toString(StringBuilder buf,int indentLevel); }
where
PVField
to which this PVAuxInfo
is attached.PVScalar
of type scalarType.PVScalar
with the specified key.interface PVScalar extends PVField { Scalar getScalar(); }
PVField
typesThe interfaces for primitive data types are:
interface PVBoolean extends PVScalar { boolean get(); void put(boolean value); } interface PVByte extends PVScalar { byte get(); void put(byte value); } interface PVShort extends PVScalar { short get(); void put(short value); } interface PVInt extends PVScalar { int get(); void put(int value); } interface PVLong extends PVScalar { long get(); void put(long value); } interface PVUByte extends PVScalar { byte get(); void put(byte value); } interface PVUShort extends PVScalar { short get(); void put(short value); } interface PVUInt extends PVScalar { int get(); void put(int value); } interface PVULong extends PVScalar { long get(); void put(long value); } interface PVFloat extends PVScalar { float get(); void put(float value); } interface PVDouble extends PVScalar { double get(); void put(double value); }
NOTE: The interface for each unsigned integer is the same as for the same signed type. This is because Java does not implement unsigned primitive types.
The interface for string is:
interface PVString extends PVScalar, SerializableArray { String get(); void put(String value); }
PVArray
is the base interface for
all the other array interfaces. It extends PVField
and provides the
additional methods:
interface PVArray extends PVField, SerializableArray { Array getArray(); int getLength(); void setLength(int len); int getCapacity(); void setCapacity(int len); boolean isCapacityMutable(); void setCapacityMutable(boolean isMutable); }
PVField
is not mutable then an exception is
thrown. If this is greater than the capacity setCapacity
is called.The interface for each array type has get and put methods which have the
same arguments except for the data type. For example for PVDoubleArray
it is:
public class DoubleArrayData { public double[] data; public int offset; } interface PVDoubleArray extends PVScalarArray { int get(int offset, int len, DoubleArrayData data); int put(int offset, int len, double[]from, int fromOffset); void shareData(double[] from); }
Get "exposes" it's internal array by setting data.data and data.offset. The
caller is responsible for copying the array elements. This violates the
principle that objects should not expose their internal data but is done for
efficiency. For example it makes it possible to copy between arrays with
identical element types via a call to System.arraycopy
without requiring an
intermediate array.
Both get
and put
return the number of elements actually transferred. The
arguments are:
PVArray
.data.data
to it's internal array and data.offset
to the offset
into the array. The caller is responsible for the actual data
transfer.from
The caller must be prepared to make multiple calls to retrieve or put an entire array. A caller should accept or put partial arrays. For example the following reads an entire array:
double[] getArray(PVDoubleArray pv) { int len = pv.getLength(); double[] storage = new double[len]; DoubleArrayData data = new DoubleArrayData(); int offset = 0; while(offset < len) { int num = pv.get(offset,(len-offset),data); System.arraycopy(data.data,data.offset,storage,offset,num); offset += num; } return storage; }
NOTE: The pvDataCPP now enforces COW (Copy on Write) for arrays.
In the future pvDataJava should have similar rules but without the concept of const
it may not be possible to enforce COW.
shareData
definitely violates COW if any code changes the shared data.
It should not used except for immutable arrays.
shareData
results in the PVArray
using the primitive array that is passed to
this method. This is most useful for immutable arrays. In this case the caller
must set the PVArray
to be immutable. If the PVArray
is not immutable then
the application is responsibility for coordinating access to the array.
This violates the principle that objects should not expose their internal data but
is important for immutable arrays. For example pvData defines
many enumerated structures where an enumerated structure has two fields: index
and choices. Choices is a PVStringArray
that holds the enumerated choices.
Index is a PVInt
that is the index of the currently selected choice. The
choices can be immutable. Allowing the choices internal String[] to be shared
between all the instances of an enumerated structure saves on storage. Another
reason for allowing shared data is so that an application which processes an
array can be separated into multiple modules that directly access the internal
data array of a PVArray
. This can be required for minimizing CPU overhead. In
this case it is the applications responsibility to coordinate access to the
array.
interface PVScalarArray extends PVArray { ScalarArray getScalarArray(); } public class BooleanArrayData { public boolean[] data; public int offset; } interface PVBooleanArray extends PVScalarArray { int get(int offset, int len, BooleanArrayData data); int put(int offset, int len, boolean[]from, int fromOffset); void shareData(boolean[] from); } public class ByteArrayData { public byte[] data; public int offset; } interface PVByteArray extends PVScalarArray { int get(int offset, int len, ByteArrayData data); int put(int offset, int len, byte[]from, int fromOffset); void shareData(byte[] from); } interface PVUByteArray extends PVScalarArray { int get(int offset, int len, ByteArrayData data); int put(int offset, int len, byte[]from, int fromOffset); void shareData(byte[] from); } public class ShortArrayData { public short[] data; public int offset; } interface PVShortArray extends PVScalarArray { int get(int offset, int len, ShortArrayData data); int put(int offset, int len, short[]from, int fromOffset); void shareData(short[] from); } interface PVUShortArray extends PVScalarArray { int get(int offset, int len, ShortArrayData data); int put(int offset, int len, short[]from, int fromOffset); void shareData(short[] from); } public class IntArrayData { public int[] data; public int offset; } interface PVIntArray extends PVScalarArray { int get(int offset, int len, IntArrayData data); int put(int offset, int len, int[]from, int fromOffset); void shareData(int[] from); } interface PVUIntArray extends PVScalarArray { int get(int offset, int len, IntArrayData data); int put(int offset, int len, int[]from, int fromOffset); void shareData(int[] from); } public class LongArrayData { public long[] data; public int offset; } interface PVLongArray extends PVScalarArray { int get(int offset, int len, LongArrayData data); int put(int offset, int len, long[]from, int fromOffset); void shareData(long[] from); } interface PVULongArray extends PVScalarArray { int get(int offset, int len, LongArrayData data); int put(int offset, int len, long[]from, int fromOffset); void shareData(long[] from); } public class FloatArrayData { public float[] data; public int offset; } interface PVFloatArray extends PVScalarArray { int get(int offset, int len, FloatArrayData data); int put(int offset, int len, float[]from, int fromOffset); void shareData(float[] from); } public class DoubleArrayData { public double[] data; public int offset; } interface PVDoubleArray extends PVScalarArray { int get(int offset, int len, DoubleArrayData data); int put(int offset, int len, double[]from, int fromOffset); void shareData(double[] from); } public class StringArrayData { public String[] data; public int offset; } interface PVStringArray extends PVScalarArray { int get(int offset, int len, StringArrayData data); int put(int offset, int len, String[]from, int fromOffset); void shareData(String[] from); } public class StructureArrayData { public PVStructure[] data; public int offset; } interface PVStructureArray extends PVArray { StructureArray getStructureArray(); int get(int offset, int length, StructureArrayData data); int put(int offset,int length, PVStructure[] from, int fromOffset); void shareData(PVStructure[] from); } public class UnionArrayData { public PVUnion[] data; public int offset; } interface PVUnionArray extends PVArray{ UnionArray getUnionArray(); int get(int offset, int length, UnionArrayData data); int put(int offset,int length, PVUnion[] from, int fromOffset); void shareData(PVUnion[] from); }
NOTES:
PVStructureArray.getNumberFields()
returns 1, i.e.
the field looks like a leaf field.The interface for a structure is:
interface PVStructure extends PVField , BitSetSerializable{ Structure getStructure(); PVField[] getPVFields(); PVField getSubField(String fieldName); PVField getSubField(int fieldOffset); <T extends PVField> T getSubField(Class<T> c, String fieldName); <T extends PVField> T getSubField(Class<T> c, int fieldOffset); // The following are convenience methods // Note that they are no longer needed because of above generic methods PVBoolean getBooleanField(String fieldName); PVByte getByteField(String fieldName); PVShort getShortField(String fieldName); PVInt getIntField(String fieldName); PVLong getLongField(String fieldName); PVFloat getFloatField(String fieldName); PVDouble getDoubleField(String fieldName); PVString getStringField(String fieldName); PVScalarArray getScalarArrayField(String fieldName); PVStructureArray getStructureArrayField(String fieldName); PVStructure getStructureField(String fieldName); PVArray getArrayField(String fieldName,ScalarType elementType); PVUnion getUnionField(String fieldName); PVUnionArray getUnionArrayField(String fieldName); public boolean checkValid(); }
where
PVStructure
. If the field does not exist null is
returned. fieldName can be the name of an immediate subfield. More
generally it can be the name of the field relative to the PVStructure
.
In other words it consists of one or more strings separated by periods (.s).
The last of these strings is the name of the field. The other strings are
the names of the structure subfields containing the requested field starting
with the highest level subfield and descending to the leaf field, e.g.
current.alarm.status.fieldOffset
, where fieldOffset
is relative to
the top-level structure. This returns null if the specified field is not
located within this PVStructure
.PVDataCreate
is an interface that provides methods that create PVField
interfaces. A factory is provided that creates PVDataCreate
.
interface PVDataCreate { PVField createPVField(Field field); PVField createPVField(PVField fieldToClone); PVScalar createPVScalar(Scalar scalar); PVScalar createPVScalar(ScalarType fieldType); PVScalar createPVScalar(PVScalar scalarToClone); <T extends PVScalar, TA extends PVScalarArray> T createPVScalar( PVScalarType<T, TA> scalarType); PVScalarArray createPVScalarArray(ScalarArray array); PVScalarArray createPVScalarArray(ScalarType elementType); PVScalarArray createPVScalarArray(PVScalarArray arrayToClone; <T extends PVScalar, TA extends PVScalarArray> TA createPVScalarArray( PVScalarType<T, TA> elementType); PVStructureArray createPVStructureArray(StructureArray structureArray); PVUnionArray createPVUnionArray(UnionArray unionArray); PVUnionArray createPVVariantUnionArray(); PVStructure createPVStructure(Structure structure); PVStructure createPVStructure(String[] fieldNames,Field[] fields); PVStructure createPVStructure(PVStructure structToClone); PVUnion createPVUnion(Union union); PVUnion createPVVariantUnion(); PVUnion createPVUnion(PVUnion unionToClone); PVStructureArray createPVStructureArray(Structure structure); PVUnionArray createPVUnionArray(Union union); PVField[] flattenPVStructure(PVStructure pvStructure); }where
PVField
is created reusing the Field
interface. Two methods are
provided. Each calls the corresponding createPVScalar
, createPVArray, or
createPVStructure
depending in the type of the argument.PVScalar
. Three versions are supplied. The
first is passed an introspection interface. The second provides the field
name and the scalarType. The third provides a field name and a PVScalar
to
clone. The newly created PVScalar
will have the same auxInfos as the
original.
The last is a generic version that casts to the appropriate type.
An example is:
PVDouble value = pvDataCeate.createPVScalar(PVScalarType.pvDouble);
PVArray
. Three versions are supplied. The first
is passed an introspection interface. The second provides and the elementType.
The third provides an array to clone.
The newly created PVArray
will have the same values as the original.
The last is a generic version that casts to the appropriate type.
An example is:
PVDoubleArray value = pvDataCeate.createPVScalarArray(PVScalarType.pvDouble);
PVStructureArray
. It must be passed a structureToClone. This
will become the Structure
interface for ALL elements of the
PVStructureArray
. It MUST be used to create any new array elements.PVUnionArray
. It must be passed a union. This
will become the union interface for ALL elements of the
PVUnionArray
. It MUST be used to create any new array elements.PVUnionArray
.
Each array element can have any type.
PVStructure
. Three methods are provided. The
first method uses a previously created structure introspection interface.
The second called with fieldName array and a Field
array.
The third initializes the subfields by cloning the fields contained in
structToClone
. The newly created subfields will have the same values and
AuxInfos as the original. If structToClone
is null then the new structure
is initialized to have 0 subfields.PVUnion
.
Two versions are provided.
The first is passed a Union
interface the single subfield.
The second is passed a PVUnion
to clone.
PVUnion
.
The subfield can have any type.
PVField
s for the fields in the PVStructure
. The
order is according to fieldOffset
.NOTE: copying immutable array fields. If an entire immutable array
field is copied to another array that has the same elementType, both offsets
are 0, and the length is the length of the source array, then the shareData
method of the target array is called and the target array is set immutable.
Thus the source and target share the same primitive array.
This section describes the supported conversions between data types.
PVArray
s that satisfy one of the following.
PVUByte
is converted to short then the proper conversion will
be done.interface Convert { void getFullFieldName(StringBuilder builder,PVField pvField) void getString(StringBuilder buf,PVField pv, int indentLevel); void getString(StringBuilder buf,PVField pv); void fromString(PVScalar pv,String from); void fromString(PVScalarArray pv,String from); int fromStringArray(PVScalarArray pv, int offset, int len, String[]from, int fromOffset); int toStringArray(PVScalarArray pv, int offset, int len, String[]to, int toOffset); boolean isCopyCompatible(Field from, Field to); void copy(PVField from,PVField to); boolean isCopyScalarCompatible(Field from, Field to); void copyScalar(PVField from, PVField to); boolean isCopyScalarArrayCompatible(ScalarArray from, ScalarArray to); int copyScalarArray(PVScalarArray from, int offset, PVScalarArray to, int toOffset, int len); boolean isCopyStructureCompatible(Structure from, Structure to); void copyStructure(PVStructure from, PVStructure to); boolean isCopyUnionCompatible(Union from, Union to); void copyUnion(PVUnion from, PVUnion to); boolean isCopyStructureArrayCompatible(StructureArray from, StructureArray to); void copyStructureArray(PVStructureArray from, PVStructureArray to); boolean isCopyUnionArrayCompatible(UnionArray from, UnionArray to); void copyUnionArray(PVUnionArray from, PVUnionArray to); // For the following the pv Type must be PVByte, ...., PVDouble byte toByte(PVField pv); short toShort(PVField pv); int toInt(PVField pv); long toLong(PVField pv); float toFloat(PVField pv); double toDouble(PVField pv); String toString(PVScalar pv); void fromByte(PVField pv, byte from); void fromShort(PVField pv, short from); void fromInt(PVField pv, int from); void fromLong(PVField pv, long from); void fromUByte(PVField pv, byte from); void fromUShort(PVField pv, short from); void fromUInt(PVField pv, int from); void fromULong(PVField pv, long from); void fromFloat(PVField pv, float from); void fromDouble(PVField pv, double from); // For the following the element type must be pvByte, ...., pvDouble int toByteArray(PVScalarArray pv, int offset, int len, byte[]to, int toOffset); int toShortArray(PVScalarArray pv, int offset, int len, short[]to, int toOffset); int toIntArray(PVScalarArray pv, int offset, int len, int[]to, int toOffset); int toLongArray(PVScalarArray pv, int offset, int len, long[]to, int toOffset); int toFloatArray(PVScalarArray pv, int offset, int len, float[]to, int toOffset); int toDoubleArray(PVScalarArray pv, int offset, int len, double[]to, int toOffset); int fromByteArray(PVScalarArray pv, int offset, int len, byte[]from, fromOffset); int fromShortArray(PVScalarArray pv, int offset, int len, short[]from, fromOffset); int fromIntArray(PVScalarArray pv, int offset, int len, int[]from, fromOffset); int fromLongArray(PVScalarArray pv, int offset, int len, long[]from, fromOffset); int fromUByteArray(PVScalarArray pv, int offset, int len, byte[]from, fromOffset); int fromUShortArray(PVScalarArray pv, int offset, int len, short[]from, fromOffset); int fromUIntArray(PVScalarArray pv, int offset, int len, int[]from, fromOffset); int fromULongArray(PVScalarArray pv, int offset, int len, long[]from, fromOffset); int fromFloatArray(PVScalarArray pv, int offset, int len, float[]from, fromOffset); int fromDoubleArray(PVScalarArray pv, int offset, int len, double[]from, fromOffset); void newLine(StringBuilder builder, int indentLevel); }
The array methods all return the number of elements copied or converted.
This can be less than len
if the
PVField
array contains less than len elements.
newLine
is a convenience method
for code that implements toString
It
generates a newline and inserts blanks at the beginning of the newline.
The getString methods dump the data in the metadata syntax described in the
pvData project overview. Note that the toString
methods of PVField
are
implemented by calling these convert methods.
Warning:
The concept of StandardField
is closely related to property which is described below.
The section on property provides details about alarm,
timeStamp, display, control, and enumerated.
That section should be read in conjunction with this section.
A standard field is a field that tools know how to use. pvData defines and provides support for the following standard fields.
interface StandardField { Structure scalar(ScalarType scalarType,String properties); Structure scalarArray(ScalarType elementType, String properties); Structure structureArray(Structure structure,String properties); Structure enumerated(); Structure enumerated(String properties); Structure alarm(); Structure timeStamp(); Structure display(); Structure control(); Structure booleanAlarm(); Structure byteAlarm(); Structure shortAlarm(); Structure intAlarm(); Structure longAlarm(); Structure floatAlarm(); Structure doubleAlarm(); Structure enumeratedAlarm(); }where
Structure
that has a scalar field named value and with the
specified ScalarType
.
The structure can have additional fields that are properties of the value field.
properties is some combination of
alarm, timeStamp, display, control, and valueAlarm.Structure
that has a scalarArray field named value and with the
specified element type.
The structure can have additional fields that are properties of the value field.
properties is some combination of
alarm, timeStamp, display, and control.Structure
Structure
.Structure
.Structure
.Structure
.Structure
.Structure
.Structure
.Structure
.Structure
.Structure
.Structure
.Structure
.interface StandardPVField { PVStructure scalar(ScalarType type,String properties); PVStructure scalarArray(ScalarType elementType, String properties); PVStructure structureArray(Structure structure,String properties); PVStructure enumerated(String[] choices); PVStructure enumerated(String[] choices,String properties); }where
PVStructure
that has a scalar field named value and with the
specified ScalarType
.
The structure can have additional fields that are properties of the value field.
properties is some combination of
alarm, timeStamp, display, control, and valueAlarm.PVStructure
that has a scalarArray field named value and with the
specified elementType.
The structure can have additional fields that are properties of the value field.
properties is some combination of
alarm, timeStamp, display, and control.PVStructure
that has a structureArray field named value and with the
specified structure as the introspection interface for each array element.
The structure can have additional fields that are properties of the value field.
properties is some combination of alarm and timeStamp.PVStructure
.
The choices field is initialized with choices and set immutable.
PVStructure
that has an enumerated structure field named value.
The choices field of value is initialized with choices and set immutable.
The structure can have additional fields that are properties of the value field.
properties is some combination of
alarm, timeStamp, and enumeratedAlarm.Assume that code wants to access two fields from a PVStructure
:
PVDouble
.The following code uses introspection to get the desired information.
String getValueAndTimeStamp(PVStructure pvStructure) { PVField valuePV = pvStructure.getSubField("value"); if(valuePV==null) { return "value field not found"; } if(valuePV.getField.getType!=Type.scalar) { return "value field is not a scalar"; } Scalar scalar = (Scalar)valuePV.getField(); if(scalar.getScalarType!=ScalarType.pvDouble) { return "value field is not a double"; } PVDouble pvDouble = (PVDouble)valuePV; PVField timeStampPV = pvStructure.getSubField("timeStamp"); if(timeStampPV==null) { return "timeStamp field not found"; } double value = valuePV.get(); return value + " timeStamp " + timeStampPV.toString(); }
Example of creating a scalar field.
PVDataCreate pvDataCreate = PVDataFactory.getPVDataCreate(); PVDouble pvValue = pvDataCreate.createPVScalar(ScalarType.pvDouble);
Create a structure.
FieldCreate fieldCreate = FieldFactory.getFieldCreate(); PVDataCreate pvDataCreate = PVDataFactory.getPVDataCreate(); PVStructure create() { Field[] fields = new Field[2]; String[] fieldNames = new String[2]; fields[0] = fieldCreate.createScalar(ScalarType.pvLong); fields[1] = fieldeCreate.createScalar(ScalarType.pvInt); fieldNames[0] = "a"; fieldNames[1] = "b"; PVStructure pvStructure = pvDataCreate.createPVStructure( fieldNames,fields); return(pvStructure); }
FieldBuilder provides an easier way to accomplish the previous:
PVStructure create() { return pvDataCreate.createPVStructure( fieldCreate.createFieldBuilder() .add("a",ScalarType.pvLong) .add("b",ScalarType.pvInt) .createStructure()); }
StandardPVField also provides an easy way to create fields. For example:
StandardPVField standardPVField = StandardPVFieldFactory.getStandardPVField(); PVStructure pvStructure = standardPVField.scalar( ScalarType.pvDouble, "alarm,timeStamp.display,control,valueAlarm");
This package provides factories and classes to implement everything defined in package org.epics.pvdata.pv Look at the code for details.
A field can have properties provided by other fields in the same structure. Often this field has the name value A record can have multiple value fields, which can appear in the top-level structure of a record or in a substructure. All other fields in the structure containing a value field are considered properties of the value field. The field name is also the property name. The value field can have any type, i.e. scalar, scalarArray, or structure. Typical property fields are timeStamp, alarm, display, control, and history. The timeStamp is a special case. If it appears anywhere in the structure hierarchy above a value field it is a property of the value field.
For example the following top-level structure has a single value field. The value field has properties alarm, timeStamp, and display.
structure counterOutput double value alarm_t int severity 0 int status 0 string message double value display_t double limitLow 0.0 double limitHigh 10.0 string description "Sample Description" string format "%f" string units volts
The following example has three value fields each with properties alarm and timeStamp. Voltage, Current, and Power each have a different alarms but all share the timeStamp.
structure powerSupplyValue double value alarm_t int severity 0 int status 0 string message structure powerSupplySimple alarm_t int severity 0 int status 0 string message timeStamp_t long secondsPastEpoch int nanoseconds int userTag powerSupplyValue_t voltage double value alarm_t int severity 0 int status 0 string message powerSupplyValue_t power double value alarm_t int severity 0 int status 0 string message powerSupplyValue_t current double value alarm_t int severity 0 int status 0 string message
The following field names have special meaning, i.e. support properties for general purpose clients.
elementType
being a scalar typeIn addition a structure can have additional fields that support the value field but are not recognized by most general purpose client tools. Typical examples are:
The model allows for device records. A device record has structure fields that that support the pvData data model. For example a powerSupport record can have fields power, voltage and current that each support the pvData data model.
Interface and factory for finding a field within a structure.
interface PVProperty { PVField findProperty(PVField pvField,String fieldName); PVField findPropertyViaParent(PVField pvField,String propertyName); String[] getPropertyNames(PVField pvField); }where
PVField
. The fieldName
is of the form name.name... pvField
must be named value or it does not
have properties. public class PVPropertyFactory { public static PVProperty getPVProperty(); }
This section has structure definitions that support standard properties. These definitions are defined in project javaIOC.
A timeStamp is represented by the following structure
structure timeStamp long secondsPastEpoch int nanoseconds int userTag
The Epoch is the POSIX epoch, i.e. Jan 1, 1970 00:00:00 UTC. Both the seconds and nanoseconds are signed integers and thus can be negative. Since the seconds is kept as a 64 bit integer, it allows for a time much greater than the present age of the universe. Since the nanoseconds portion is kept as a 32 bit integer it is subject to overflow if a value that corresponds to a value that is greater than a little more than 2 seconds of less that about -2 seconds. The support code always adjust seconds so that the nanoSecconds part is normalized, i. e. it has is 0<=nanoseconds<nanoSecPerSec..
The Java definition of a timeStamp is:
interface TimeStamp { static final long milliSecPerSec = 1000; static final long microSecPerSec = milliSecPerSec*milliSecPerSec; static final long nanoSecPerSec = milliSecPerSec*microSecPerSec; static final long posixEpochAtEpicsEpoch = 631152000; void normalize(); long getSecondsPastEpoch(); long getEpicsSecondsPastEpoch(); int getNanoseconds(); int getUserTag(); void setUserTag(int userTag); void put(long secondsPastEpoch,int nanoseconds); long getMilliSeconds(); void put(long milliSeconds); void getCurrentTime(); boolean equals(TimeStamp other); boolean lt(TimeStamp other); boolean le(TimeStamp other); void add(long seconds); void add(double seconds); double diff(TimeStamp a,TimeStamp b); }
where:
The TimeStamp class provides arithmetic and comparison methods for time stamps. The result is always kept in normalized form, which means that the nanosecond portion is 0≤=nano<nanoSecPerSec. Note that it is OK to have timeStamps for times previous to the epoch.
class TimeStampFactory implements TimeStamp { public static TimeStamp create(); }
interface PVTimeStamp { boolean attach(PVField pvField); void detach(); boolean isAttached(); void get(TimeStamp timeStamp); boolean set(TimeStamp timeStamp); }where
pvField
It returns (false,true) if a
timeStamp structure is found. It looks first at pvField
itself and if is
not an appropriate pvData structure but the field name is value it looks
up the parent structure tree.TimeStamp
. An exception is
thrown if not attached to a pvData structure. TimeStamp
to the pvData structure. An exception is
thrown if not attached to a pvData structure. class PVTimeStampFactory implements PVTimeStamp { public static PVTimeStamp create(); }
An alarm structure is defined as follows:
structure alarm int severity int status string message
Note that severity and status are NOT defined as enumerated structures. The reason is performance, i.e. prevent passing the array of choice strings everywhere. The AlarmStatus and AlarmSeverity provide the equivalent of choices for an enumerated structure.
Alarm Severity defines the possible alarm severities
enum AlarmSeverity { NONE,MINOR,MAJOR,INVALID,UNDEFINED; public static AlarmSeverity getSeverity(int value); private static final String[] alarmSeverityNames; public static String[] getSeverityNames() { return alarmSeverityNames;} }where
Alarm Status defines the possible alarm status conditions
enum AlarmStatus { NONE,DEVICE,DRIVER,RECORD,DB,CONF,UNDEFINED,CLIENT; public static AlarmStatus getStatus(int value); private static final String[] alarmStatusNames; public static String[] getStatusNames() { return alarmStatusNames;} }where
class Alarm { public Alarm(); public String getMessage(); public void setMessage(String message); public AlarmSeverity getSeverity(); public void setSeverity(AlarmSeverity alarmSeverity); public AlarmStatus getStatus(); public void setStatus(AlarmStatus alarmStatus); }where
interface PVAlarm { boolean attach(PVField pvField); void detach(); boolean isAttached(); void get(Alarm alarm); boolean set(Alarm alarm); }
where
pvField
It returns (false,true) if
it found an appropriate pvData structure. It looks first a pvField itself
and if is not an appropriate pvData structure but the field name is value
it looks to see if the parent structure has an appropriate sub
structure.Alarm
. An exception is
thrown if not attached to a pvData structure. Alarm
to the pvData structure. An exception is thrown
if not attached to a pvData structure. class PVAlarmFactory implements PVAlarm{ public static PVAlarm create(); }
Control information is represented by the following structure
structure control double limitLow double limitHigh double minStep
class Control { Control(); double getLow(); double getHigh(); double getMinStep(); void setLow(double value); void setHigh(double value); void setMinStep(double value); }
where
interface PVControl { boolean attach(PVField pvField); void detach(); boolean isAttached(); void get(Control control); boolean set(Control control); }
where
pvField
It returns (false,true) if
it found an appropriate pvData structure. It looks first PVField
itself
and if is not an appropriate pvData structure but the field name is value
it looks to see if the parent structure has an appropriate sub-structure.
Control
. An exception is
thrown if not attached to a pvData structure. Control
to the pvData structure. An exception is
thrown if not attached to a pvData structure. class PVControlFactory{ public static PVControl create(); }
Display information is represented by the following structure
structure display double limitLow double limitHigh string description string format string units
class Display { Display(); double getLow(); double getHigh(); void setLow(double value); void setHigh(double value); String getDescription(); void setDescription(String value); String getFormat(); void setFormat(String value); String getUnits(); void setUnits(String value); }
where
interface PVDisplay { boolean attach(PVField pvField); void detach(); boolean isAttached(); void get(Display display); boolean set(Display display); }
where
pvField
It returns (false,true) if
it found an appropriate pvData structure. It looks first a pvField itself
and if is not an appropriate pvData structure but the field name is value
it looks to see if the parent structure has an appropriate sub
structure.Display
. An exception is
thrown if not attached to a pvData structure.Display
to the pvData structure. An exception is
thrown if not attached to a pvData structure. PVDisplay
instance. Attach must be called before get or set
can be called.class PVDisplayFactory implements PVDisplay{ public static PVDisplay create() }
An enumerated structure is a structure that has fields:
structure int index string[] choices
interface PVEnumerated { boolean attach(PVField pvField); void detach(); boolean isAttached(); boolean setIndex(int index); int getIndex(); String getChoice(); boolean choicesMutable(); String[] getChoices(); boolean setChoices(String[] choices); }
where
pvField
It returns (false,true) if
pvField (is not, is) an enumerated structure.class PVEnumeratedFactory{ PVEnumerated create(); }
NOTE: This is not currently used by anything. Bob sees it as an important facility in the future.
MultiChoice is support for a multiChoice structure, which is a structure containing two fields:
public interface MultiChoice { interface Choices { String[] getChoices(); int getNumberChoices(); } byte[] getBitMask(); String[] getChoices(); Choices getSelectedChoices(); void setBit(int index); void clear(); int registerChoice(String choice); }
where
public class MultiChoiceFactory{ public static MultiChoice getMultiChoice(PVField pvField); }
This package provides utility code:
BitSet
that can be serialized.ThreadCreate
and Executor
ArrayList
and does not require the
implementation to allocate storage for the nodes.Timer
that does not require an object to be
created for each timer request.This is adapted from the java.util.BitSet. It adds serializable. See
java.util.BitSet
for a description. This implementation adds the following
additional methods:
public boolean getAndSet(int bitIndex); public void set(BitSet src); public void or_and(BitSet set1, BitSet set2);
where
bitSet
This is an implementation of BitSet
that supports serialization, which the
standard Jave implementation does not allow.
interface BitSetUtil { boolean compress(BitSet bitSet,PVStructure pvStructure); }
This provides functions that operate of a BitSet for a PVStructure
. It
currently has only one method:
BitSet
related to a structure.class BitSetUtilFactory { public static BitSetUtil getCompressBitSet(); }
public class MessageNode { public String message; public MessageType messageType; }
public interface MessageQueue { MessageNode get(); boolean put(String message,MessageType messageType,boolean replaceLast); boolean isEmpty(); boolean isFull(); int getClearOverrun(); }
This is for use by code that wants to handle messages without blocking higher priority threads.
MessageNode
is a class with two public data members:
MessageQueue
is an interface with methods:
replaceFirst
or replaceLast
have been called
since the last call to getClearOverrun
. The internal counter is reset to
0.public class MessageQueueFactory { public static MessageQueue create(int size); }where
MessageQueue
and return the interface.public enum ThreadPriority { lowest, lower, low, middle, high, higher, highest; public static final int[] javaPriority; public int getJavaPriority(); public static int getJavaPriority(ThreadPriority threadPriority); }
interface ThreadReady { void ready(); }
interface RunnableReady { void run(ThreadReady threadReady); }
interface ThreadCreate { Thread create(String name, int priority, RunnableReady runnableReady); Thread[] getThreads(); }
public class ThreadCreateFactory { public static ThreadCreate getThreadCreate(); }
ThreadCreate provides two features:
ReadyRunnable.run
calls
ThreadReady.ready()
.An Executor
is a thread that can execute any object that implements the Java
Runnable
interface. The user can request that a single command be executed. If
the command is already in the list of commands to be executed it is NOT added
to the list when add is called.
public interface ExecutorNode {}
public interface Executor { ExecutorNode createNode(Runnable command); void execute(ExecutorNode executorNode); void stop(); }
public class ExecutorFactory { static public Executor create(String name,ScanPriority priority); }where
TimeFunction is a facility that measures the average number of seconds a
function call requires. When timeCall
is called, it calls function in a loop.
It starts with a loop of one iteration. If the total elapsed time is less then
.1 seconds it increases the number of iterations by a factor of 10. It keeps
repeating until the elapsed time is greater than .1 seconds. It returns the
average number of seconds per call.
public interface TimeFunctionRequester { void function(); }
public interface TimeFunction { double timeCall(); }
public class TimeFunctionFactory { public static TimeFunction create(TimeFunctionRequester requester); }
LinkedList implements a double linked list that requires a user to allocate
the nodes. It is more efficient that ArrayList
for implementing stacks and
queues. For lists that are traversed while new elements can be added or
removed, LinkedListArray
provides a way to get an array of the current
elements without allocating a new array each time the array is traversed.
LinkedListArray
converts a LinkedList
to an LinkNode
array. The
implementation provided by LinkedListFactory
only creates a new LinkNode
array
w.en the number of elements in the linkedList passed to setNodes is greater
than the length of the current LinkNode
array.
public interface LinkedListNode<T> { public T getObject(); boolean isOnList(); }
public interface LinkedList { void addTail(LinkedListNode<T> listNode); void addHead(LinkedListNode<T> listNode); void insertAfter(LinkedListNode<T> listNode,LinkedListNode<T> addNode); void insertBefore(LinkedListNode<T> listNode,LinkedListNode<T> addNode); LinkedListNode<T> removeTail(); LinkedListNode<T> removeHead(); void remove(LinkedListNode<T> listNode); void remove(T object); LinkedListNode<T> getHead(); LinkedListNode<T> getTail(); LinkedListNode<T> getNext(LinkedListNode<T> listNode); LinkedListNode<T> getPrev(LinkedListNode<T> listNode); boolean isEmpty(); boolean contains(T object); }
public interface LinkedListArray<T> { void setNodes(LinkedList<T> linkedList); LinkedListNode<T>[] getNodes(); int getLength(); void clear(); }
public class LinkedListCreate<T> { public static LinkedList<T> create(); public static LinkedListNode<T> createNode(Object object); public static LinkedListArray<T> createArray(); }
LinkedListCreate is created as follows:
LinkedListCreate<SomeObject> linkedListCreate = new LinkedListCreate<SomeObject>();
Then a linked list can be created as follows:
LinkedList<SomeObject> linkedList = linkedListCreate.create();
The only way a node can be allocated is by calling
linkedListCreate.createNode(object)
. The object passed to createNode
is what is returned by LinkedList.getObject
. For example:
private static class SomeObject { private LinkedListNode<SomeObject> listNode = null; // other definitions private Node(/* arguments*/) { listNode = linkedListCreate.createNode(this); } LinkedListNode<SomeObject> getListNode() {return listNode}; } // then SomeObject someObject = new SomeObject(/* args */); linkedList.addTail(someObject);
A node can only be on one list at a time but can be put, at different times, on different lists as long as they all hold the same type of objects.
The class does not provide a lock but the user can synchronized via calls like:
synchronized(linkedList) { linkedList.addTail(listNode); }
The following is an example of how to use LinkedListArray.
LinkedListNode<SomeObject>[] nodes = null; int length = 0; synchronized(linkedList) { linkedListArray.setNodes(linkedList); nodes = linkedListArray.getNodes(); length = linkedListArray.getLength(); } for(int i=0; i<length; i++) { SomeObject object = nodes[i].getObject(); // do something with object }
This provides a general purpose timer. It provides the following features
not provided by java.util.Timer
and java.util.TimerTask
:
TimerTask
has been canceled
or a delay TimerTask
has run, the TimerTask
can not be reused. Instead a
new TimerTask
must be created. A TimerNode
can be reused.interface Timer { interface TimerCallback { void callback(); void timerStopped(); } interface TimerNode { void cancel(); boolean isScheduled(); } void scheduleAfterDelay(TimerNode timerNode,double delay); void schedulePeriodic(TimerNode timerNode,double delay,double period); void stop(); }
This is the interface for scheduling a timer callback. A timer is created by
calling TimerFactory.create
. It has the methods:
TimerCallback.timerStopped
is called
immediately.TimerCallback.timerStopped
is called immediately.TimerCallback.timerStopped
is
called for each element of the queue. Further schedule calls result in a
call to TimerCallback.timerStopped
. Once stopped a timer is no longer
useful. A new timer must be created.class TimerFactory { static public Timer create(String threadName, ThreadPriority priority); static public TimerNode createNode(TimerCallback timerCallback); }
This is the factory that implements the Timer
and TimerNode
interfaces. It
has the methods:
TimerNode
. A TimerNode
can be used to schedule any timer but a
TimerNode
can only be on a single timer queue and only once on a given
timer queue.This is an interface that must be implemented by the user. It has the following methods:
TimerNode.cancel
below.Timer.stop
was called when a timer request was queued. or if the timer
is stopped and a schedule request is made.This is an interface implemented by TimerFactory
. It is allocated by calling
TimerFactory.createNode
. It is passed as an argument when scheduling a
callback. It has the single method:
This provides a queue which has an immutable capacity, which is specified
when the queue is created. When the queue is full the user code is expected to
keep using the current element until a new free element becomes available. This
is used by pvData.monitor
.
public class QueueCreate<T> { public Queue<T> create(QueueElement<T>[] queueElements) { return new QueueImpl<T>(queueElements); } public QueueElement<T> createQueueElement(T object) { return new QueueElementImpl<T>(object); } }
public interface QueueElement<T> { public T getObject(); }
public interface Queue<T> { void clear(); int getNumberFree(); int capacity(); QueueElement<T> getFree(); void setUsed(QueueElement<T> queueElement); QueueElement<T> getUsed(); void releaseUsed(QueueElement<T> queueElement); }
The queue methods are:
A QueueCreate
instance is created via a call like the following:
QueueCreate<MyObject> queueCreate = new QueueCreate<MyObject>();
Once a queueCreate is available a queue instance is created via code like the following:
Queue<MyObject> queue create(MyObject[] myObjects) { QueueElement<MyObject>[] queueElements = new QueueElement[length]; for(int i=0; i<length; i++) { QueueElement<MonitorElement> queueElement = queueCreate.createQueueElement(myObjects[i); queueElements[i] = queueElement; } return queueCreate.create(queueElements); }
A producer calls getFree
and setUsed
via code like the following:
MyObject getFree() { QueueElement<MyObject> queueElement = queue.getFree(); if(queueElement==null) return null; return queueElement.getObject(); }
A consumer calls getUsed and releaseUsed via code like the following:
while(true) { QueueElement<MyObject> queueElement = queue.getUsed(); if(queueElement==null) break; MyObject myObject = queueElement.getObject(); // do something with myObject queue.releaseUsed(queueElement); }
This is a base interface used by many other interfaces.
interface Destroyable { void destroy(); }
where
This is a helper class for serialization, which is required for sending and receiving pvData over the network.
class SerializeHelper { static void writeSize(final int s, ByteBuffer buffer); static int readSize(ByteBuffer buffer); static void serializeString(final String value, ByteBuffer buffer); static void serializeSubstring(final String value, int offset, int length, ByteBuffer buffer); static String deserializeString(ByteBuffer buffer); }
where
copy is not used in this project. It is intended for use by pvAccess and by channel providers. It is provided with this project because the code depends only on pvData itself.
copy provides the ability to create a structure that has a copy of an arbitrary subset of the fields in an existing top level structure. In addition it allows global options and field specific options. It has two main components: createRequest and pvCopy. Given a string createRequest creates a pvRequest, which is a PVStructure that has the format expected by pvCopy.
In addition pvCopy supports filter plugins. pvData implements the following filters: array, deadband, timestamp, ignore. See the developerGuide for details.
In addition the plugin API supports implementing additional plugins.
Copy provides:
This is mainly used by pvAccess clients. Given a request string it creates a pvRequest structure that can be passed to the pvAccess create methods. In turn pvAccess passes the pvRequest to a local channel provider which then passes it to pvCopy.
The definition of the public members is:
class CreateRequest { ... static CreateRequestPtr create(); virtual PVStructurePtr createRequest(String const &request); String getMessage(); };
An example of how it is used is:
CreateRequestPtr createRequest = CreateRequest::create(); PVStructurePtr pvRequest = createRequest->createRequest(request); if(pvRequest==NULL) { String error = createRequest->getMessage(); // take some action } else { //success do something }
The definition of the public members is:
class epicsShareClass PVCopyTraverseMasterCallback { ... virtual void nextMasterPVField(PVFieldPtr const &pvField); }; class class epicsShareClass PVCopy { ... static PVCopyPtr create( PVStructurePtr const &pvMaster, PVStructurePtr const &pvRequest, String const & structureName); PVStructurePtr getPVMaster(); void traverseMaster(PVCopyTraverseMasterCallbackPtr const & callback); StructureConstPtr getStructure(); PVStructurePtr createPVStructure(); size_t getCopyOffset(PVFieldPtr const &masterPVField); size_t getCopyOffset( PVStructurePtr const &masterPVStructure, PVFieldPtr const &masterPVField); PVFieldPtr getMasterPVField(std::size_t structureOffset); void initCopy( PVStructurePtr const ©PVStructure, BitSetPtr const &bitSet); void updateCopySetBitSet( PVStructurePtr const ©PVStructure, BitSetPtr const &bitSet); void updateCopyFromBitSet( PVStructurePtr const ©PVStructure, BitSetPtr const &bitSet); void updateMaster( PVStructurePtr const ©PVStructure, BitSetPtr const &bitSet); PVStructurePtr getOptions(std::size_t fieldOffset); ... };where
PVStructure
created.
pvMaster
.
pvMaster
.
For each field the callback is called.
PVStructure
for copy.
PVStructure
, multiple top-level structures
will be created.
pvMaster
.
return the offset in copy for the same field.
A value of String::npos means that the copy does not have this field.
Two overloaded methods are provided. The first is called if
the field of master is not a structure. The second is for
subfields of a structure.
copyPVStructure
by giving each field the value from the corresponding field in pvMaster
.
bitSet
will be set to show that all fields are changed.
This means that bit set will have the value {0}.
copyPVStructure
to the value of the corresponding field
in pvMaster
. Each field that is changed has it's corresponding
bit set in bitSet.
copyPVStructure
to the value
of the corresponding field in pvMaster
.
pvMaster
to the value
of the corresponding field in copyPVStructure
.
PVStructure
is
a structure with a set of PVString
subfields that specify name,value
pairs. name is the subField name and value is the subField value.
monitor is not used in this project. It is intended for use by pvAccess and by channelProviders. It provided with this project because the code depends only on pvData itself. It is support code for channel providers that implement channel monitor. It provides support for monitor queues.
class MonitorElement { MonitorElement(PVStructurePtr const & pvStructurePtr); PVStructurePtr pvStructurePtr; BitSetPtr changedBitSet; BitSetPtr overrunBitSet; }; class Monitor { virtual Status start() = 0; virtual Status stop() = 0; virtual MonitorElementPtr poll() = 0; virtual void release(MonitorElementPtr const & monitorElement) = 0; }; class MonitorRequester : public virtual Requester { virtual void monitorConnect(Status const & status, MonitorPtr const & monitor, StructureConstPtr const & structure) = 0; virtual void monitorEvent(MonitorPtr const & monitor) = 0; virtual void unlisten(MonitorPtr const & monitor) = 0; };
MonitorElement holds the data for one element of a monitor queue. It has the fields:
A queue of monitor elements must be implemented by any channel provider that implements Channel::createMonitor. For an example implementation look at pvDatabaseCPP. It has the following:
typedef Queue<MonitorElement> MonitorElementQueue; typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr; class MultipleElementQueue : public ElementQueue { public: POINTER_DEFINITIONS(MultipleElementQueue); virtual ~MultipleElementQueue(){} MultipleElementQueue( MonitorLocalPtr const &monitorLocal, MonitorElementQueuePtr const &queue, size_t nfields); virtual void destroy(){} virtual Status start(); virtual Status stop(); virtual bool dataChanged(); virtual MonitorElementPtr poll(); virtual void release(MonitorElementPtr const &monitorElement); ... };
Monitor must be implemented by any channel provider that implements Channel::createMonitor. Remote PVAccess also implements Monitor on the client side. Note that each client has it's own queue that is not shared with other client.
Monitor has the following methods:
poll
and release
.
This must be implemented by a pvAccess client. It has the methods:


These are Ghanian names that are given to children according the day of the week your born.Names in Ghana are driven from the day of the week


ui-state
ui.router.state
Much like ui-sref, but will accept named $scope properties to evaluate for a state definition, params and override options.
<ANY ui-state="{string}" ui-state-params="{Object}" ui-state-opts="{Object}"> ... </ANY>
| Param | Type | Details |
|---|---|---|
| ui-state | string | 'stateName' can be any valid absolute or relative state |
| ui-state-params | Object | params to pass to $state.href() |
| ui-state-opts | Object | options to pass to $state.go() |


Welcome to Kyanon
Kyanon Digital is an Agile digital production outsourcing company
Join us now :
http://kyanon.com/
You good at coding and finding an intership place ?


This tiny shortener only supports sites with HTTPS/HTTP, URLs without it will be invalid.
API endpoint is available at /shorturl, post request with header url:<URL to be shortened>
/shorturl


A weather dashboard to tell me the forecast for a city that I search.
An application for craft beer lovers and breweries to search, favorite, and blog about craft breweries.
About "Find Next Gig" an app to find out the next time a band or artist has a gig.
A work day scheduler calendar application.
An application where user can enter and delete burgers they would like to eat to and from a database.
A personal note taker created with Node and Express.
A command line interface to generate a team roster with individual employee information for team management.
A content management system to store employee information.
A password generator using random numbers and special characters.
A command line README generator for quick, efficient project README's.


A selected window is defined as the window that output will be sent to. It can be invisible. When a program starts execution, the selected window is the main Run window.
This means that you can only call the function by calling Window.Select, not by calling Select.


I am working on a project at the Max Planck Institute for European Legal History in Frankfurt to produce an authoritative, trilingual edition in Latin, English, and Spanish of the second volume of Juan de Solórzano y Pereira’s De Indiarum Iure, known as De Gubernatione (1639).
De Indiarum Iure is an important source not only for scholars of colonial Latin America but also for researchers working on early-modern colonialism more generally. Despite being an important text for scholars of Latin America and legal historians in particular, this text has been little studied and its content is often better known through Politica Indiana, Solórzano’s Spanish version of the two Latin volumes, which was published in 1647. Although a Spanish translation of the first volume of De Indiarum Iure in Latin and Spanish was published by the Consejo Superior de Investigaciones Científicas, there is no modern edition or translation of the second volume.
The aim of this project is to make De Gubernatione much more accessible not only by translating it, but also by collaborating with a group of researchers from different backgrounds to produce a study of the text. As the project develops, there will be a colloquium and the resulting collection of essays will accompany the edition. This will help bring Solórzano to a broader range of scholars and stimulate the debate about how this text can be read and used.
My contribution to the project is to translate the text into English and Spanish and also to write two essays about the text: one analysing the Latin of the text, and the other examining how Solórzano uses Classical authors to construct and inform his arguments.


The application of linear algebra in engineering is very extensive and in-depth, and Linear Algebra provides a beautiful mathematical interpretation of the real world. You may use it in different engineering fields, e.g. spatial coordinate transformation, wavelet analysis, Fourier transform, image processing, parameter identification, etc., all of which require you to have a solid knowledge of linear algebra. There are also many classic online open courses and resources. Actually, you will find that linear algebra is thoroughly interesting! This post will use PCA as an example to quickly browse through some important basic ideas of linear algebra. In the last semester, linear algebra was used in many courses, I'd better sort it out.
If you are or have ever been a student from engineering, you must be very familiar with Fourier transformation that can transform a continuous periodic time domain signal to a discrete aperiodic frequency domain signal. Generally, in the time domain, the signal doesn't give us clear enough information, but in the frequency domain, we can find which frequencies own the relative higher amplitudes and then rank them. PCA is just like this (but not the same, PCA does lossy compression), it tries to find the principle components of the given data. that usually requires a new interpretation of the original data.
In order to save memory, it is usually necessary to reduce the dimension of the data, as shown in the two-dimensional space of the following figure. If they are required to compress in one dimension space, that is, a line, how to select this line to make the error of reconstruction smallest? Obviously, u1 wins. The main task of PCA is like the following:
Suppose we have n data (x1, x2,…, xn) in the Rd space, and the design matrix X in Rnxd. We want to do some lossy comression to decrease the dimension to d^', meanwhile we hope not to damage the represental accuracy of the original data (i.e. the variance of the transformed data should be maximal). Thus, we should find a linear transformation L in Rd^'xdto project the origin data to a best hyperplane. The data after transformation is represented as
\begin{equation} y_i =L x_i \end{equation}where yi in Rd^'. Let Y in Rnxd^'be the design matrix of the output of transformation. The row of Y is transpose of y vector, so we have:
\begin{equation} Y = X L^T \end{equation}Two principles:
Let's first look at the example in the following figure. Suppose we have 2 features and 3 data.
The covariance matrix of X is represented as:
\begin{equation} C_x=\frac{1}{n} X^T X \end{equation}The covariance matrix of Y is denoted as:
\begin{equation} C_y=\frac{1}{n} Y^T Y = \frac{1}{n} L X^X L^T = L C_x L^T = M^T c_x M \end{equation}So, we should find out the M so that covariance of the features equal 0, and the variance of the features are maximal. which also means that cy is optimized to be diagonal. If cy is positive definit, it turns out that the best M has eigenvectors of cy as its columns. We know that if cy is positive definit, we can always find out the eigenvectors of cy which is orthognal or orthonormal. So the final linear transformation for lossy compression is matrix with the d^' eigenvector as rows, which correspond to the d^' largest eigenvalues. AN example is shown in the following figure.
This is easy to understand, suppose we have 3 times 3 matrix A, we can regard the determinant of A as and the volume with three eigenvalues representing the length of 3 edges. So the larger the eigenvalue is, the more the Matrix 'A' is "stretched" in that direction.
Besides, the problem is equal to do SDV of matrix X. the sigular value is just the eigenvalue of XT X.