<tr><td>zmapStyleUtils.c</td><td>Print functions for debugging</td></tr>
<tr><td>zmapStyle.c</td><td>Implementation of the style objects</td></tr>
<tr><td>zmapFeatureUtils.c</td><td>No style specific data or functions</td></tr>
<tr><td>zmapFeatureTypes.c</td><td>Pre-defined styles and inheritance</td></tr>
<tr><td>more to come...</td></tr>
</tbody>
</table>
<tableborder="1"cellpadding="3">
<thead><tr><th>Headers</th><th></th></tr><thead>
<tbody>
<tr><td>zmapStyle.h</td><td>Contains all the config strings, similar to zmapConfigStrings.c</td></tr>
<tr><td>zmapStyle_I.h </td><td>Private style data structures</td></tr>
<tr><td>more to come...</td></tr>
</tbody>
</table>
</p>
</fieldset>
<aname="terminology"></a>
<fieldset><legend>Terminology</legend>
<p><b>Features</b> are organised in <b>columns</b> on the ZMap display, a group of these is known as a <b>featureset</b>.</p>
<p>
...
...
@@ -21,7 +49,7 @@ EST_human is a <b>column</b> that contains the <b>feature sources</b> EST_human
</fieldset>
<aname=mapping></a>
<aname="mapping"></a>
<fieldset><legend>Mapping features (data sources) to featureset (display columns) and feature style</legend>
<h3>Source to feature set</h3>
<p>Traditionally, ACEDB provided this mapping during ZMap startup, but without an ACEDB connection we have no way of recieving this data.</p>
...
...
@@ -45,7 +73,7 @@ Note that this implies that feature attributes can only be added to or changed b
</p>
</fieldset>
<aname=identity></a>
<aname="identity"></a>
<fieldset><legend>Identifying a featureset</legend>
A featureset has a original_id and a unique_id (see zmapFeature.h) - the original_id is as given in a config file or from a database and is regarded as case insensitive. This is stored as as a GQuark and is translated into an internal_id which is in lower case, and for some features also includes extra information as necessary.</p>
<p> There are functions (eg <b>zMapFeatureSetCreateID()</b> - simple lower casing) that do this. <i>(Need some more notes here).</i>
...
...
@@ -58,6 +86,8 @@ A featureset has a original_id and a unique_id (see zmapFeature.h) - the origina
</pre>
These are hash tables that map a featureset unique_id to another data structure.</p>
<p>According to zmapViewRemoteReceive.c/xml_featureset_start_cb() <b>zmapView->source_2_featureset</b> is a hash table of <b>ZMapGFFSet</b> and <b>zmapView->source_2_sourcedata</b> is a hash table of <b>ZMapGFFSource</b>. We presume that the id fields relate to unique_id rather than original_id (styles have both, as for featuresets).</p>
<p><b>NOTE</b>:In the ACEDB interface, ACE provides the source to featureset data. The View should merge these data together if there is more than one such server bit at present only the first one is used (see <b>zmapView.c/processDataRequests()</b>, search for 'needs sorting'). This data is used by the X-Remote interface when requesting certain data sources (eg on-the-fly (OTF) alignments). The ZMap config file lists featuresets supported by ACE and the source to featureset daat from ACE specified how further un-configured data sources mapp onto the known featuresets. This is particularly relevant when searching for which server to request data from.
</p>
<pre>
/* Struct for "feature set" information. Used to look up "meta" information for each feature set. */
typedef struct
...
...
@@ -82,7 +112,106 @@ typedef struct
<b>zmapServer/acedb/acedbServer.c/parseMethodStyleNames()</b> set up a similar list with different featureset and style names.
</p>
<p>Some related information from <b>zmapGFF2Parser.c</b>: "NOTE the feature sets style has the same name as the feature set" - this relates to featureset expressed as a display column.</p>
<p><b>NOTE:</b>In <b>zmapFeatureContext.c/zMapFeatureString2QuarkList()</b> the function <b>zMapStyleCreateID()</b> is used to get a feature ID, or so it seems... This function is used to make a list of featureset names in <b>zmapViewConnect()</b>.
<p><b>NOTE:</b>In <b>zmapFeatureContext.c/zMapFeatureString2QuarkList()</b> the function <b>zMapStyleCreateID()</b> is used to get a feature ID, or so it seems... This function is used to make a list of featureset names in <b>zmapViewConnect()</b>. It turns out that <b>zMapFeatureCreateId()</b> simlpy calls <b>zmapStyleCreateID()</b></p>
</fieldset>
<aname="styles"></a>
<fieldset><legend>Styles: use</legend>
<h3>Inheritance rules</h3>
<p>These appear to be:
<ul>
<li>attributes are copied from parent to child, including whether or not the value is set.
<li>there is no limit on levels
<li>a child can have one parent only
<li>once the style mode is set it cannot be unset or changed
<li>an implied mode will set the mode (eg if a mode specific attibute is set)
</ul>
</p>
<h3>Merging styles</h3>
<p>
If a new version of an existing style is merged into the existing then the new takes priority.
</p>
<h3>Default values</h3>
<p>
These are defined by GLib for attributes (parameters) in the case of integer values but not others, so using GLib directly to define defaults is not a good option.<br/>
Colours default to the fill colour if not specified.<br/>
There is a 'default bump mode' which is an attribute in its own right.
</p>
<p><i>zmapStyle does not implement explicit default values for style attributes</i>.</p>
<h3>Modes</h3>
<p>Each style has a mode which defines which one out of a number of option sets may be used. These option sets are mutually exclusive (for example for an alignment feature it is not valid to define a 'graph-baseline'). Attempts to set a mode specific paramter in a style with a different mode will fail and a warning added to zmap.log. If a style's mode is not set then setting a mode specific parameter will set the mode implicitly - this is to allow definition of inherited styles in any order.
</p>
</fieldset>
<aname="styles_impl"></a>
<fieldset><legend>Styles: implementation</legend>
<h3>Original method</h3>
<p>This was done using GObjects and configuration files read in using GKeyFile functions. A large number of parameters have been defined and access functions implemented, and this has become unwieldy. Some complicated copy functions have been written to cope with data not explicitly defined by GObject parameters, most notably the 'is a parameter set' flags and the mode dependant parameters</p>
<h3>March 2010 Implementation</h3>
<p><b>I'm still working on this! Don't believe a word of it</b></p>
<p>We still use GObjects but a number of aspects of the original implementation are changed:
<ul>
<li>The many interface functions have been kept - they are used extensively by acedbServer.c. They provide type checking and are therefore useful.
<li>The parameters have been re-arranged such that all the styles data can be expressed transparently as a GObject parameter, which will allows the complicated copy functions to be removed. Every item in the style structure corresponds to a GObject parameter, but
it may be possible for two GObject paramters to refer to a single struct member eg original-id as a quark and name as the string representation of the quark.
<li>A table driven approach has been adopted which allows parameters to be defined as data. Extensive use of <b>offsetof()</b> and type casts has been used to allow the very long switch statements to be removed and paramters coded according to the type of thier data, saving approx 2000 lines of code.
<li>The 'is-parameter-set' flags are coded and handled automatically. Note that this implies that due to the use of offsetof() in the internal Styles code that bit fields must be seperately addressable and coded as <b>gboolean</b> rather than <b>uint:1</b>.
<li>'implied mode' has been removed, but a styles mode will be set automatically if a mode dependant paramter is set.
<li>Mode dependant flags are now stored globally. The mode data union is still a union but the 'is-set' flags for them are not.
<li>Colour specifications still have thier own 'is-set' flags for thier sub-features.
<li>Quarks and enums are traed like integers, but not that ANSI C does not define theier size, and therefore the size fo each parameter is calculated in the style class initialisation.
<li>The <b>ZMapStyleColourTarget</b> enum has been removed and its function replace by the <b>ZMapStyleParamId</b> enum.
</ul>
</p>
<h4>Interaction with config file code</h4>
<p>It's possible to get quite confused by quarks. The existing config file code defines some parameters as strings and at some point turns these into quarks via a callback from a callback. As the styles code handles string to quark conversion with much less complexity there is no need for this and it would be simpler to present this data as strings. However as the previous interface to the styles code had certain string values defined as integers it may be best to preserve this: there are the file config and acedb interfaces to consider, and both must be kept in step.
</p>
<p>
In particular:
<ul>
<li> There is a <b>ZMapKeyValueStruct</b> with a conv_func union which is allowed to be only of type 'str2enum' which is used generally to extract enums from strings.
<li> This is subverted to introduce a string to quark conversion while masquerading as a string to enum conversion (see <b>zmapConfigLoader.c/create_config_style()</b> and <b>zMapConfigIniGetStylesFromFile()</b>, search for 'conv_func').
<li>
</ul>
</p>
<h3>Accessing mode dependant data</h3>
<p>In a frenzy of 'executive decision' making i (mh17) decreed that no mode specific data may be set without setting the mode first. This implies that a style definition (eg in a config file) must either specify the mode first or our code must fish out that option before others. NB: the function <b>zMapStyleIsDrawable()</b> insists that the mode must be set.</p>
<p>Messages will be added to the log if these errors occur.</p>
<h3>Copying Styles: some technicalities</h3>
<p>The existance of the 'is set' flags for each attribute and the mode dependant data (a union) causes some implementation difficulties, a situation that was previously solved by sub-classing zmapBase and introducing the 'deep copy' functions. These allowed data not visible to the GObject interface to be handled but at the expense of breaking the clean implementation/ design of the objects.</p>
<p>The March 2010 implementation solves these problems by making all data accessable to the GObject parameter interface and by forcing the flags and mode data to be copied first. This is done by installing these properties first and double checking at run-time that this data is in fact available when dependant attributes are accessed.</p>
<p>A g_object_get() will fail for an attribute that is not set. The function <b>zMapFeatureStyleCopy()</b> only copies parameters that have been set. A copy constructor has not been fully implemented, but if needed (right now we do not copy styles via the GValue interface) can be provided by uncommenting the function <b>zmap_feature_type_style_copy_set_property()</b>, asigning it in <b>zmap_feature_type_style_class_init()</b> and p[ossibly adjust the class's <b>GValueTable</b> as in <b>zmapBase.c</b> (which has been #iff'ed out but otherwise retained). </p>
<p>In a similiar way, mode dependant data will not be set if the selected mode is inappropriate.</p>
<p>Another strategy would be to not use a union for the mode data, which would use more memory but not a dangerous amount. </p>
<h3>Adding new Style parameters and types</h3>
<p>For a new parameter:
<ul>
<li>Add a new enum to <b>zmapStyle.h/ZMapStyleParamId</b>
<li>Add strings and data as necessary to <b>zmapConfigStrings.c</b> and <b>zmapConfigStanzaStructs.c</b> and <b>zmapConfigLoader.c</b>
<li>Add some new data to the <b>zmapStyle_I.h/ZMapFeatureStyleStruct</b>
<li>Add an entry into the array <b>zmapStyle.c/ZMapStyleParams_G</b>, taking care that it maps 1-1 to the ZMapStyleParamId enum.
</ul>
</p>
<p>For a new <i>type</i> of parameter:
<ul>
<li>Add a new enum to <b>zmapStyle_i.h/ZMapStyleParamType</b>.
<li>Adjust the six functions mentioned in the comment
</ul>
</p>
<h4>Some questions</h4>
<p>The style has a number of properties, some of which could arguably be better placed elsewhere, as they appear to relate to featuresets rather than a display style??:
<ul>
<li>current bump mode - could logically have 2 colums using the same style