text:
- 1 Overview
- 2 Data Extraction and Storage (I)
- 3 Log Transfer (II)
- 4 Retrieving metrics from the Service Provider (II)
- 5 Value Added Services (II / III)
- 5.1 Common API for Value Added Services (II)
- 5.2 Value-Added Features (II / III / PKP)
- 5.2.1 Selecting a "Main Metric" (II)
- 5.2.2 Most-Viewed Articles (II)
- 5.2.3 Search Result Ranking (III)
- 5.2.4 Search Result Ordering (III)
- 5.2.5 Most-Read Articles of the same Author (III)
- 5.2.6 "Similar" Articles (III)
- 5.2.7 Integration with the Tag Cloud Plugin (III)
- 5.2.8 Statistics Reports (PKP/Bruno)
- 5.2.9 Editors, Authors and Readers Pages (PKP/Juan)
The OA-S Project
The German Open Access Statistics (OA-S) project intends to provide a framework and infrastructure that enables OJS users to establish alternative usage statistics for Open Access content and build value added services on top of such statistics.
This specification describes the use cases, requirements and implementation recommendations for the integration of OA-S into OJS.
The basic idea of OA-S can be described as a co-operation of two institutions:
- The data provider (in this case operators of OJS installations) tracks access to documents (in our case article and issue galleys, abstracts and supplementary files).
- Access data will then be made available through a protected OAI interface and harvested by the OAS service provider.
- The service provider will clean the raw data and produce aggregate metrics based on the COUNTER standard. At a later stage LocEc and IFABC statistics may also be supported.
- The data provider retrieves metrics from the service provider on a daily basis and stores them in OJS.
These metrics can then be used in different ways in OJS:
- They can be displayed to the editors, authors and readers.
- They can be used in search for ranking.
- Editors could produce statistics reports.
- We could provide a "most viewed article" feature.
- We could implement a feature that displays "other (more viewed) articles of the same author".
- We could display "similar (more viewed) articles" on an article's page.
We'll use the terms "data provider" and "service provider" from here on without further explanation. "Data provider" and "OJS user" can be used synonymously. We use the term "end user" to refer to users accessing an OJS site.
Requirements for OJS OA-S Integration
The requirements for OJS OA-S integration can be divided into four areas:
- log data extraction and storage (OJS)
- log transfer (OJS -> OA-S)
- metrics retrieval (OA-S -> OJS)
- value added services (OJS)
The requirements in these areas are...
Log data extraction and storage:
- We log usage events for access to issue and article galleys, article abstracts and supplementary files.
- Logged data must be pseudonimized immediately.
- Logged data must be deleted immediately after it has been successfully transferred to the service provider or after it expires.
Log transfer:
- Log data must be transformed into context objects.
- We then have to provide an HTTP BASIC authenticated OAI interface from which the service provider will harvest raw log data.
Metrics retrieval:
- We retrieve final metrics data from the service provider via a JSON web service.
- Metrics data will then be stored into an OLAP data model which allows us easy data access, both granular and aggregate.
Value added services:
- Display granular (per-object) metrics to the readers, authors and editors.
- Use metrics as a search ranking criteria together with the Lucene plugin.
- Define reports on OA-S metrics similarly to already existing OJS reports.
- Implement a "most viewed articles" feature.
- Implement an "another (more viewed) articles of the same author" feature.
- Implement a feature "similar (more viewed) articles".
The following sections will provide analysis and implementation recommendations for these requirement areas. Main section titles contain Roman numbers in brackets that symbolize the project phase in which this part will be specified and implemented (I, II or III). Sections with "PKP" in their title describe features that will be implemented by PKP.
Data Extraction and Storage (I)
This section defines how we intend to log, pseudonimize and store usage events.
Log Events
We consider access to the following URLs in OJS as usage events:
article abstracts:
- ../article/view(Article)/<article-id>
- Access to ../article/view(Article)/<article-id>/<galley-id> or any other article page will NOT be counted.
article galleys:
- .../article/viewFile/<article-id>/<article-galley-id>
- .../article/download/<article-id>/<article-galley-id>
- Access to .../article/view(Article)/... and .../article/viewDownloadInterstitial/... or any other article or article galley page will NOT be counted unless the galley is a remote or HTML galley.
- NB: This differs from the usage event definition used for the current COUNTER plug-in!
supplementary files:
- .../article/downloadSuppFile/<article-id>/<supp-file-id>
- Access to .../rt/suppFileMetadata/... and .../rt/suppFiles/... or any other supp file page will NOT be counted.
issue galleys:
- .../issue/viewFile/<issue-id>/<issue-galley-id>
- .../issue/download/<issue-id>/<issue-galley-id>
- Access to .../issue/viewIssue/... and .../issue/viewDownloadInterstitial/... or any other issue page will NOT be counted to avoid double counting.
OA-S expects us to deliver certain usage event data. OA-S provides sample code for DSpace log extraction. The same code is also provided via SVN. We analyzed the specification as well as the sample code to define the following list of all required or optional data items. The corresponding proposed OJS/PHP data source has been included between parentheses:
- usage event timestamp (PHP's time() function +/- local time offset)
- administration section
- HTTP status code (will be always 200 in our case as we won't produce view events for non-200 responses)
- downloaded document size (difficult from PHP, we may use connection_aborted() to identify some incomplete downloads but this won't be reliable as PHP may end before the download actually finishes when the web server buffers (part of) the response. Stackoverflow agrees with me here.)
- actual document size (
PKPFile::getFileSize()for galleys and supplementary files, I propose 0 in the case of article abstracts, NB: not implemented in the OA-S sample code!)
- document format (MIME type,
- URI of the service (e.g. OJS journal URL,
Config::getVar('general', 'base_url'))
- referent section
- document URL (This will be the canonical "best URL" produced by
PKPRouter::url() + ...::getBest...Id())
- internal document ID (This will be an OJS-specific ID similar to the default DOI that can be produced under all circumstances and will help us to uniquely identify a document in the return data)
- optional: one or more unique document IDs (e.g. DOI, URN, etc.) (can be easily retrieved from the pubId-plugins for objects where IDs are defined)
- document URL (This will be the canonical "best URL" produced by
- referring entity section
- HTTP referrer (if available,
- optional: additional identifiers of the referring entity (e.g. DOI, ...) if available (not implemented in OJS)
- HTTP referrer (if available,
- requester section
- hashed + salted IP (
PKPRequest::getRemoteAddr()+ hashing)
- hashed C class (
PKPRequest::getRemoteAddr()+ truncation + hashing)
- hostname of the requesting entity (if available), truncated to the second level domain (recommendation: do not implemented in OJS as this would require one DNS request per view event which would be very expensive, exception: use the hostname if it is present in
$_SERVER"for free", use the algorithm from the sample code in logfile-parser/lib/oasparser.php,
- optional: classification, see the sample code, logfile-parser/lib/oasparser-webserver-dspace.php for an example (seems to be a temporary implementation, too)
- internal: Usage events due to internal requirements, e.g. automated integrity checks, availability checks, etc.
- administrative: Usage events that happen due to administrative decisions, e.g. for quality assurance. (proposal: use this category for accesses by logged in editors, section editors, authors, etc.)
- institutional: Usage events triggered from within the institution running the service for which usage events are being collected.
- optional: hashed session ID or session (recommendation: do not send)
- HTTP user agent (if available, use
- hashed + salted IP (
- service type section
- We'll designate statistics for abstracts with the "abstract" flag.
- Galleys will be flagged as "fulltext".
- Other publication objects will not be flagged.
According to OA-S information, these data items will be used for the following purposes:
- IP address and timestamp are used to recognize double downloads as defined by the COUNTER standard. Such "double clicks" will be counted as a single usage event.
- The C class of the IP address will furthermore be used to recognize robots and exclude their usage from the statistics.
- The file information (url, name, document id, url parameters, etc.) are used to uniquely identify the document which has been accessed.
- The HTTP status code will used as only successful access may be counted.
- The size of the document is used to identify full downloads (e.g. 95% of the file downloaded). Partial or aborted downloads will not be counted as usage event.
- The HTTP user agent will be used to identify robots and to remove their usage from the statistics.
- The referrer information is used to analyze how users found the service and can be used to improve the service (potential sources: search engines, organizational web portal).
To capture the required information, I recommend implementing a specialized view event hook that all statistics plug-ins can subscribe to. This allows us to better standardize OJS view events (e.g. to simulate Apache log events as much as possible) and keeps code overhead to a minimum. If an additional OJS hook should be avoided we can hook into the existing
TemplateManager::display and
FileManager::downloadFile hooks and filter these generic events to identify view events we are interested in.
If we implement a statistics event hook then I recommend that such a hook provide data items similar to the variables available in Apache's log component. This enables us to easily switch the statistics hook later, e.g. based on Apache logs or shared storage as has been proposed.
Privacy Protection
We assume that many OJS providers using the OA-S extension will be liable to German privacy laws. While OJS users will have to evaluated their legal situation on a per-case basis and we cannot guarantee in any way that OJS conforms to all legal requirements in individual cases, we provide basic technical infrastructure that may make it easier for OJS users to comply with German privacy law.
Legal Requirements
The OA-S project commissioned two legal case studies with respect to German privacy law: one describes the legal context of OA-S application at University Stuttgart, the other focuses more generally on OA-S users, especially project members. The first report has been done during an earlier phase of the OA-S project when privacy-enhancing measures, like the use of a SALT for IP hashing, were not yet specified. The second report is more recent. It assumes an enhanced privacy infrastructure, i.e. the use of a SALT to pseudonimize IP addresses. We therefore base our implementation recommendations on the results of the second report.
The report recommends that data providers liable to German privacy law implement the following infrastructure:
- All personal data must be pseudonymized immediately (within a few minutes) after being stored. This can be achieved by hashing IP addresses with a secret salt. The salt must have a length of at least 128 bits and must be cryptographically secure. The salt must be renewed about once a month and may not be known to the OA-S service provider. The salt will be distributed through a central agent to all data providers. A single salt can be used for all data providers if they do not share pseudonimized data. Pseudonimized data must be immediately transferred to the service provider and thereafter deleted by the data provider, i.e. every five minutes.
- Data providers have to provide the means for end users to deny data collection ("opt-out"). The cited report comes to the conclusion that an active "opt-in" of end users is not necessary if data will be reliably pseudonymized. It recommends an "opt-out" button which, if clicked, could result in a temporary cookie being set in the end user's browser. Whenever such a cookie is present, usage data may not be collected. The report recommends against setting a permanent cookie as this may now or in the future require active "opt-in" on the part of the end user. Alternatively the user's IP address could be blacklisted while using the service, i.e. entered into a table and all data from that IP would then not be stored. The blacklist entry would have to be deleted after the user session expires.
- Data providers have to inform end users about their right to opt out of data collection before they start using the service. They also have to inform the end user that opting out of the service will result in a temporary cookie being set in their browsers. This information must be available not only once when the user starts using the service but permanently, e.g. through a link.
- Data providers will have to implement further organizational measures (registration of data processing organizations, reporting data usage to end users on demand)
Salt Management Interface
As pointed out in the previous section, we'll have to salt our pseudomization hash function. Within the OA-S project, University Library Saarbrücken (SULB) provides a central SALT distribution mechanism as described in the OA-S technical manual for new repositories. SALTs will be provided on a monthly basis and have to be downloaded to OJS. SULB provides a Linux shell script (alternative unprotected link) to download SALTS. We rather recommend to download the SALT from with OJS directly to avoid the additional complexity of calling a shell script and to better support Windows users. The SALT can be downloaded from an HTTP BASIC protected location.
A new salt is usually being provided at the beginning of each month. We recommend the following algorithm for salt management to be implemented in OJS:
Whenever we receive a log event: IF the download timestamp of the current SALT is within the current month THEN use the current SALT to pseudonimize log data ELSE IF the "last download time" lies within the last fifteen minutes THEN use the current SALT ELSE authenticate to "oas.sulb.uni-saarland.de" download "salt_value.txt" set the "last download time" to the current time() value IF the downloaded SALT is different from the current SALT THEN replace the current SALT with the downloaded SALT set the timestamp of the SALT to the current time() value use the new SALT to pseudonimize log data ELSE use the current SALT
The OA-S sample application provides an algorithm for IP pseudomization based on the SALT value retrieved from SULB.
We recommend using this exact PHP function to pseudonimize IPs in OJS.
Opt-Out and Privacy Information
We propose to implement a small block plug-in that allows for opt-out and privacy information display. The block plug-in will provide a single "privacy" link in the sidebar.
The block plug-in will only appear on pages that may trigger a usage event, i.e. the article abstract page, the issue galley page, the article galley pages and the supplementary file page.
Clicking on the privacy link will open up a plug-in-specific page that contains the privacy information as well as an opt-out button. Clicking on the opt-out button will set a temporary cookie with a validity of one year.
If the opt-out cookie is present in the session then no OA-S statistics events will be logged at all. Cookies will be renewed whenever the user accesses OJS.
Data Storage
Statistics events have to be temporarily stored between the time they arrive and the time they're being harvested by the service provider. For intermediate data storage I recommend a plug-in specific internal database table that contains the fields mentioned in #Log Events above. Personal data (IP) must be stored in its pseudonimized form (see #Privacy Protection).
Due to privacy restrictions and to avoid scalability problems, we should delete log data as soon as it has been successfully transferred to the service provider. Unfortunately, OA-S has not yet specified a protocol that allows us to determine when data has been received by the service provider's server (Source: Email Julika 30.10.2012). OA-S uses the OAI protocol to harvest statistics data. This protocol does not support success/failure messages by itself. Harvesters usually retry access when there was a communications failure. Although access to the OAI interface is authenticated, this means that we cannot delete data whenever we receive an OAI request. We rather have to define a fixed maximum time that log data may be kept in the log and then delete it, independently of its transfer status.
We therefore recommend to save log data indexed by its time stamp. Whenever we manipulate the log table (i.e. when receiving a log event) we'll automatically delete all expired log data.
As the log expiry time will be relatively low, we do not see the necessity to rotate the log table or otherwise improve scalability.
Log Transfer (II)
Transformation into Context Objects
The chosen log format for statistics events has been kept as close as possible to the required context object specification. We'll use PHP's XML DOM to build context objects from records. This will be implemented as a simple filter class that takes a log record array as input and returns the XML DOM object as output.
OAI interface
A few properties distinguish the OAI interface required by OA-S from the default OJS OAI implementation:
- We have to protect the interface with BASIC HTTP authentication.
- We do not export meta-data about publication objects (articles, etc.) but about usage events. This also implies that data cannot be retrieved via the usual OJS database tables but must be read from the event log.
The existing data provider for OA-S context objects serves as a practical example and guideline for our work. While exact implementation details must be decided at implementation time it currently looks as if we could fully re-use the OAI base classes provided by PKP core.
We cannot re-use the JournalOAI and OAIDAO classes as they assume publication objects to be published. We also cannot reuse the existing OAIHandler as we have to provide an authenticated interface.
We therefore have to implement the following classes and methods to support the required OAI interface:
- An OA-S specific handler method which I propose to integrate in the existing plug-in handler class OasHandler.
- A subclass of the OAI class that provides the connection between the event log DAO and the OAI interface.
- An OA-S specific OAI format that converts event log data to XML context objects.
- The event log DAO will inherit from PKPOAIDAO so that a specific OAI DAO will not be necessary.
Once the OAI interface has been implemented it must be validated. OA-S provides a validator service for the data provider OAI interface.
Further information:
- The exact OAI context object format has been sufficiently specified by the OA-S project and does not have to be documented here.
- A protocol to confirm successful reception of raw data has not yet been implemented (see email Julika, 31.10.2012). This is necessary to confirm log deletion. We are implementing a timeout right now to delete log events (and to confirm to privacy regulations). See the details above.
The OA-S specification demands protecting the OA-S OAI interface with HTTP BASIC authentication. Unfortunately a more secure authentication protocol is not supported by OA-S.
To make our implementation as configuration-less as possible we recommend implementing HTTP BASIC authentication in PHP rather than relying on a web server implementation (like Apache's). See http://php.net/manual/en/features.http-auth.php for details how this can be done in PHP.
To simplify configuration we recommend using a standard username "ojs-oas" that will be the same for all OJS installations.
We recommend adding a single setting to the plugin for the password. This must be set by the end user. We preset the password with a random string so that the OAI interface will not be exposed inadvertently when first activating the OA-S plug-in.
Whenever a request to the OAI interface comes in we'll check the authentication credentials coming with the request. If they are missing we'll challenge the client with an HTTP BASIC authentication answer.
Retrieving metrics from the Service Provider (II)
The specification of the return format has not yet been officially documented by OA-S.
We do have samples of the possible return formats, though.
Here a sample JSON response:
{ "from": "2012-10-01", "to": "2012-10-30", "entrydef": ["identifier", "date", "counter", "LogEc", "IFABC", "RobotsCounter", "RobotsLogEc", "RobotsIFABC"], "entries": [ {"identifier": "oai:DeinDienst.de:00001", "date": "2012-10-10", "counter": 0, "LogEc": 0, "IFABC": 1, "RobotsCounter": 0, "RobotsLogEc": 0, "RobotsIFABC": 0}, {"identifier": "oai:DeinDienst.de:00037", "date": "2012-10-11", "counter": 0, "LogEc": 0, "IFABC": 1, "RobotsCounter": 0, "RobotsLogEc": 0, "RobotsIFABC": 0}, ... } Source: Email Julika Mimkes, 31.10.2012
And here a CSV sample:
date;identifier;counter;counter_abstract;robots 2012-11-10;oai:abc.de:00001;5;8;1 2012-11-10;oai:abc.de:02444;6;2;7 2012-11-10;oai:abc.de:05555;12;9;1 Source: Email Matthias Hitzler, 26.02.2013
According to information provided by the OA-S project (Source: Email Matthias Hitzler, 26.02.2013), the following details apply to the return interface:
- Data is made available as plain text files on a web server.
- Data arrives with a lag of three days currently. This enables the service provider to make sure that data is reliable and does not have to be revised later on.
- A SOAP/SUSHI interface is in preparation but has not yet been implemented.
- The URL of the return file server is esx-143.gbv.de/data_provider_name (test environment) and esx-144.gbv.de/data_provider_name (production environment).
- A cronjob runs on a daily, weekly or monthly basis, depending on the return interval solicited during the registration phase. The cronjob does not currently run at a specific time.
- The server provides a folder structure that makes it easy to identify available data. The path pattern is /data_provider_name/YYYY/MM/startdate_enddate.{csv,json}. Dates are given in the format 'Y-m-d'. Example: 2012-01-01_2012-01-07.csv for weekly generation or 2012-01-01_2012-01-01.csv for daily retrieval.
- Files that have been written will not change. It is therefore sufficient to poll for new files and load these.
JSON parsing support has been integrated into PHP from version 5.2 onwards. This is a rather recent version and it would be better if we could support earlier 5.x versions, too.
Reading CSV files is supported in PHP 4 and 5 as long as the CSV conforms to basic escaping protocols. To achieve a full audit trail and allow for easy re-import of files we recommend to stage statistics files locally first and load them asynchronously into the database. This combines well with the fact that OA-S provides plain text files on their server. Scanning and downloading these files will be easy and fast.
We therefore propose a load protocol that implements the following steps:
- Regularly poll the OA-S server for new data. This should be done on a daily basis and will be triggered via OJS' scheduled tasks. We'll remember the last file successfully loaded and then scan the well-known folder structure of the OA-S server for new files until we hit a 404 not found response.
- Whenever new data is available: Download the new metrics file to a well-known staging folder in the OJS files directory.
- Regularly poll the staging folder for new files. The scheduling for this will be done in the same way as for OA-S server polling.
- When a new file is present then try to parse and load it. Once we "claim" a file, we immediately remove it from the "hot" staging folder to avoid race conditions. When the parsing is successful then move the file to the file archive. Otherwise move it to the rejection folder where it can be analyzed, corrected and manually moved to the staging folder again.
- When a file contains data that has been loaded before then the last write wins. This guarantees that the loading process will be fully idempotent.
If data is lost in the database then files can be moved from the archive back to the staging folder where they'll be discovered and automatically loaded again.
The cronjob configuration requirements will be documented in a README and on the plugin settings page. Polling and loading can also be triggered by user action. This is implemented through an "update statistics data" button on the plugin settings page and is meant as a fallback for those who are unable to or do not want to configure a cron job.
See the specification of the metrics table below for a detailed description of the load target.
Value Added Services (II / III)
Common API for Value Added Services (II)
Some of the use cases for value added services require us to integrate various usage statistics in the same place (e.g. OAS, COUNTER/OJS, ALM). Examples of this would be:
- display of all article-specific metrics to end readers on the article abstract page
- selection of a metric for search ranking
- cross-metric reports for OJS editors.
To implement such use cases, we need an implementation-agnostic cross-plugin API that allows us to treat statistics from various sources conformly. Thus I recommend two additions to core OJS:
- A specialized plug-in API similar to the API for public identifiers to be implemented by all ReportPlugin classes.
- A multi-dimensional online analytical processing (OLAP) database table for metric storage.
The following two sections will describe our recommendations for these additions in more detail.
Plug-In API
The proposed metrics API allows granular access to any number of metrics provided by different plug-ins. If there are several metric types, we have to define a site- or journal-specific primary metric type which will then be used where a single "most important" metric is required (e.g. for search ranking). We propose that such a selection is done in the site or journal settings by the journal manager or OJS admin respectively.
I propose a change to the
ReportPlugin base class. Similarly to
PubIdPlugin, this class could serve as a plug-in agnostic metric provider:
- Statistics plug-ins (e.g. COUNTER, OA-S, ALM) should provide a
- If a plug-in needs hooks (e.g. to track usage events) it should be nested in a
We recommend the following specific API for
getMetrics($metricType = null, $columns = null, $filters = null, $orderBy = null, $range = null)
- These methods should return
nullin case of plug-ins that do not wish to provide metrics, e.g. the current articles, reviews and subscriptions reports
- The exact meaning of the input variables will be explained in a later section (see below).
Furthermore we recommend the following specific API for OJS objects (application, journal, issue, issue and article galleys, articles, supplementary files).
getMetrics($metricType = null, $columns = null, $filters = null, $orderBy = null, $range = null)to return a report with the given publication object pre-filtered.
- This is for convenience only as we have quite a few use cases with that filter on a single publication object. These methods should only be implemented when actually needed.
- These methods return
nullin case metrics are not defined for the given object or filter.
Article/ArticleGalley/IssueGalley/SuppFile::getViews()would be renamed to
...::getMetrics()with the above signature throughout OJS.
- If no
$metricTypeis given for
getMetric()then the main/primary metric type will be used.
- This API can be extended to issues and journals for aggregate metrics retrieval.
- The exact meaning of the input variables will be explained in a later section (see below).
The journal and application object will be extended to return information required to configure a main metric for the respective context:
- Both objects contain a
getDefaultMetricType()that will return the currently configured main metric type (or
nullif no default metric can be found).
- Both objects contain a
getMetricTypes()that returns the metric types available for selection as potential main metric in the respective context.
- See the interface specification for main metric selection below.
Plugins can internally decide whether to actually retrieve metrics from the
MetricsDAO (see next paragraph) or whether to retrieve metrics from an external location (e.g. a web service).
Metrics Table
It is entirely possible to specify a common data model for aggregate metrics storage in OJS as OJS front-end statistics use cases are common to all statistics plug-ins. We therefore recommend to consolidate the current plug-in specific metrics stores into a single metrics table.
While saving on development time and complexity, such a table is crucial to implement responsive and flexible cross-metrics reporting, too. Among other front-end use cases, such a table will help us in our goal to replace plug-in specific reports with a simple report generator for all metrics. It would also help us to implement requirements as "time-based reporting" or any other use case that requires access to aggregate metrics data (which are most!) in a simple and efficient way across all metrics plugins.
Having local aggregate metrics data is necessary to provide speedy reports. I do not believe that building cross-metric aggregate reports based on on-the-fly access to a remote web service can be done reliably and with acceptable response times. Plugins like ALM that choose to implement a plug-in specific metrics storage or wish to retrieve metrics from a web service on the fly will still be able to integrate with all OJS front-end features through the API described in the previous paragraph.
Conceptually, the proposed table represents a multi-dimensional OLAP cube. It allows both, granular (drill down) and aggregate (dice and slice), access to metrics data.
The proposed cube has the following properties...
- publication object (represented by assocId + assocType)
- time (day)
- metric ("OJS/COUNTER", "OA-S/COUNTER", "ALM-Facebook", ...)
Aggregation hierarchies over these dimensions:
- publication object: assocType
- publication object: article -> issue -> journal (as aggregation hierarchy, not the objects themselves)
- time: month -> year
Additional dimensions may have to be defined to cater to special administrative or front-end use cases, such as
- geography: Where did the usage events originate from?
- source file: This enables us to implement a scalable file based, restartable load process. Details of such a process are not in scope of this document.
- ...
- Facts would be represented as a single integer or float data type dimensioned as just outlined.
- Dimensions should be modeled additively so that we can use them in reports that "slice" and "dice" the conceptual data cube. This excludes "from-to" notation for the date.
- Monthly data that is not available on a daily basis can be modeled additively in such a table by leaving the day-aggregation level empty.
This is pretty much a standard OLAP design and should therefore serve all aggregate data needs that may come up in reports or elsewhere.
While the conceptual level seems rather complicated, we can implement such a conceptual model with a single additional table in core OJS as all dimension tables either already exist in the database or could be implemented "virtually" by on-the-fly aggregation, e.g. for the date hierarchy.
We therefore propose a single new database table 'metrics' with the following columns:
- assoc_id: foreign key to article, article or issue galley, supplementary file
- assoc_type: determining the type of the assoc id (article, article or issue galley, supplementary file)
- submission_id, issue_id, context_id: denormalized entries for the publication dimension for improved performance and simplified aggregation
- day: the lowest aggregate level of the time dimension
- month (optional): required only if we want to support month-only aggregation, either because some metrics cannot be provided on a daily basis or to compress historical data
- file_type (optional): the type of download, e.g. HTML, PDF, other.
- metric_type: e.g. "oas::counter", "ojs::counter", "alm::facebook", etc.
- load_id: a plug-in specific load identifier used to implement a restartable and scalable load process, e.g. a file name, file id or run id
- country_id (optional): the highest aggregate level of the source geography dimension
- region (optional): the mid aggregate level of the source geography dimension
- city (optional): the lowest aggregate level of the source geography dimension
- metric: an integer column that represents the aggregate metric
Indexes should be placed only when really needed by actual reports so that load performance can be optimized.
The number of data items in the proposed table will be considerably less than what we currently need to store raw event data. I therefore do not believe that such a table will reach the underlying database's scalability limit. If such a thing would happen we could still purge old metric data or reduce the granularity of historic data (e.g. from per-day to per-month).
For a simple estimate we assume the following maximum dimension cardinality:
- assocId/assocType: 3000
- day: 365 * 10 = 3650
- metricType: 5
- loadId is not included in the calculation as we assume that there will be at most a single load ID per day which makes loadId isomorphic to the day dimension
- country is not included as we do not intend to implement this dimension for the time being
We further assume completely dense data (which gives us an upper bound way above the probable data distribution).
Under these pessimistic assumptions we get a maximum of 3000 * 3650 * 5 = 54.75 * 10^6 rows which is comfortably within the range supported by current MySQL versions and probably way above what even large OJS installations will ever encounter. Compressing historical data per day will provide a further theoretical compression ratio of 12:365 (about 96%) for completely dense data. In practice compression ratios will be lower with non-dense data but probably still well above 50%.
Access to the metrics table would be mediated through a MetricDAO. The MetricDAO should provide methods to insert/update metrics and to administer scalable load processes. The MetricDAO should never be used for direct metrics access except for access from statistics plugins that will route data through their getReport()-API. This allows us to support common front-end features for plug-ins like ALM even if those do not support access through the MetricDAO.
Input and Output Formats (Aggregation, Filters, Metrics Data)
To support our use cases through a common API, our input format should support the following filter and aggregation requirements:
- specify dimension hierarchy elements for columns ("dicing") to define the aggregation level
- specify report-level filters ("slicing") through one of...
- dimension element ranges (for ordered dimensions)
- dimension element selection (for discrete dimensions)
- specify the result order
- specify result ranges (for use cases like paging, "top 10", etc.)
More specifically the input format will consist of...
Metrics selection (
- The metrics dimension is special for two reasons: It is not additive and it cannot be sensibly ordered.
- This means that...
- It must either be included on column level or a single metric must be chosen as a report-level filter.
- It does not make sense to filter it by range.
- Advantages of implementing metrics selection as a separate, mandatory input parameter are...
- We automatically enforce consistency with the additional restrictions of the dimension.
- The common scenario that a single metric value or a list of metrics should be retrieved for a publication object can be conveniently supported without a complex column/filter specification.
- The default metrics API becomes very similar to the API for public IDs which makes it easier to understand and use in most cases.
- It has to be kept in mind, though, that conceptually, metrics are just another dimension. Future extensions to the API should not repeat the same pattern for other dimensions unless there are similarly compelling reasons for it. Additional dimensions should usually be supported through the $filter/$columns/... variables as specified below!
- The semantics of the
$metricTypevariable is like this...
- Setting
nullor not setting it at all will select the main/primary metric and the metric column will not be included in the report.
- Setting
If no further columns are specified then a single scalar value will be returned.
- Setting
$metricTypeto a scalar value will select that metric as a report-level filter without selecting it as a column. If no further columns are specified then a single scalar value will be returned.
- Setting
$metricTypeto an unordered array of several metric dimension elements will select those metrics as report-level filters and at the same time include the metrics column in the report.
- Setting
$metricTypeto "*" will select all metrics available in the given context (i.e. publication object, plug-in etc.) and at the same time include the metrics column in the report.
- Setting
An optional dimension hierarchy specification (
- The
$columnsvariable is an unordered (non-hashed) array.
- The array contains a list of identifiers (PHP constants) for the lowest hierarchy aggregation level to be included in the report.
- The available constants are
- Obs.: The
STATISTICS_DIMENSION_{CONTEXT_ID,ISSUE_ID,SUBMISSION_ID}constants are aggregation-level columns! Use them to include the article/issue/journal IDs additionally to the publication object's own ID. When an ID on a given level is not available (e.g. an
SUBMISSION_IDfor issue galley statistics) then the value of that column will be
- Precisely zero or one value can be defined for each aggregation hierarchy. There may be several values per dimension if, and only if, there are several aggregation hierarchies for that dimension (e.g. authors and assocType for the publication object dimension). The dimension hierarchy specification will be checked for consistency wrt this requirement before executing the report.
- A single scalar value can be given in case a single column should be specified.
- Dimension hierarchies not included in this specification will be aggregated over (implicit selection of the top hierarchy level).
- The input variable could probably be named
$aggregationor something with
$dimension...in it for better conceptual consistency. I chose to name it
$columns, though, so that those who do not have a firm grip of OLAP concepts immediately understand what this actually means.
- If no value is given (empty array) then the lowest available granularity (all dimensions) should be used.
An optional report-level filter specification (
- The
$filtervariable is a hashed array.
- It contains identifiers (PHP constants) for the filtered hierarchy aggregation level as keys. The constants are the same as for the dimension hierarchy specification above, see there.
- As values it either contains a hashed array with from/to entries with two specific hierarchy element IDs in case of a range filter or an unordered array of one or more hierarchy element IDs in case of an element selection filter.
- If only a single element is to be filtered then the value can be given as a single ID rather than an array.
- If no filter is given for a dimension then it is assumed that data should be aggregated over all dimension elements (implicit selection of the top hierarchy element).
- If no filter is given at all then all dimensions will be aggregated over.
An optional result order specification (
- The
$orderByvariable is a hashed array.
- It contains identifiers (PHP constants) for the filtered hierarchy aggregation level as keys. The constants are the same as for the dimension hierarchy specification above, see there. If you want to order by the metric value then you can use the constant
- For each identifier you can specify one of the two values "asc" (
STATISTICS_ORDER_ASC) or "desc" (
- It can only include hierarchy aggregation levels that have also been specified in
$columns. The order specification will be checked for consistency wrt this requirement before executing the report.
An optional result range specification ($range): This is the usual PKP paging object
DBResultRange. If no range is given then a maximum of
STATISTICS_MAX_ROWS rows will be returned.
With this input design in mind we can make usage recommendations for access APIs specified in previous paragraphs (access through report plugins, publication objects and the
- Cross-metrics (plugin-agnostic) reports (e.g. on site, journal or article level) can best be supported by direct access to the
MetricsDAO. Otherwise we'd have to implement ordering and paging in PHP code which would be unnecessarily complex and slow. We therefore propose that plug-ins that do not wish to store their data in the metrics table will hook into calls to the
MetricsDAOand insert their own results into the intermediate result from the
MetricsDAObefore returning it to the client.
- Access to specific metrics or metrics that can be served from a single plug-in should always be done through the plug-in API so that plug-ins that do not want to hook into the MetricsDAO will be supported ootb for these use cases.
Output format:
- We return report data in flat tabular format through the usual db results iterator (
DAOResultFactory) from the various getReport() versions.
- We include all hierarchy levels above the specified dimension hierarchy levels as columns by default. This adds no relevant additional cost on the database side and considerably simplifies our input format.
- Dimension hierarchy columns will appear in a pre-defined order. Clients will have to re-order the columns if needed.
Further implementation details:
- To keep our API as simple as possible, we do not provide a full cross-table implementation but rather place all dimensions into columns followed by a single aggregate fact column. If it turns out that more advanced cross-table requirements exist somewhere in the front-end then flat tabular data will have to be "pivoted" on the fly. This can be done through a standard transformation function somewhere in the OJS core. As not all supported database versions support pivoting, we have to do this in PHP anyway.
- Currently all our dimensions are discrete and can be ordered somehow (except for the metric type, see above). So we support dimension element ranges and selection without further restrictions. Some of the possible filter settings may not make a lot of sense, though (e.g. summing up metrics for countries from 'D' to 'F' or selecting completely disparate dates). I don't think it's necessary to implement further restrictions, though. Users get what they ask for. ;-)
- When calling the API from the context of a publication object then publication object may neither be included as a column nor as a filter.
- When calling the API from the context of a plug-in then only metrics available from that plug-in may be selected.
- We do not support filtering based on aggregate metric data (e.g. "all articles with accesses > 100 in the last year"). That said: most requirements like this can can be simulated by combining ranges, ordering and dimension selection anyway.
- Support for this API can easily be implemented within the
MetricsDAOdue to the design of proposed metrics table:
- Dimension selection corresponds precisely to a
SELECTstatement on that table.
- Dimension filtering corresponds precisely to a
WHEREstatement on the same table or on one of the (potentially virtual) dimension hierarchy columns.
- Ordering can be easily implemented with a
ORDER BYclause.
- Result ranges can be defined through the standard paging mechanism.
- Dimension selection corresponds precisely to a
- Specific reporting use cases can be tuned by introducing further aggregates (for better "dicing" support) or indexes (for "slices" that select at most a one-digit percentage of the cube). We do not implement such support unless it turns out in practice that certain use cases could not be implemented otherwise.
Value-Added Features (II / III / PKP)
Most of the following features are publicly available to all OJS users (readers). Plugin activation and configuration is always a journal manager's task. We'll only indicate role permissions when deviating from this default.
Selecting a "Main Metric" (II)
Based on the metrics API it will be possible to choose a "main metric" in the site and journal settings. Site-level configuration will be available to administrators and journal-level configuration to journal managers. Users with these roles will be presented with a list of all currently available metrics and may choose the one that should be used for features that need a single metric to be defined (e.g. the most-viewed articles feature).
The list of metrics in the site settings will contain only site-level plugins while the list in the journal settings will contain site-level plugins plus statistics plugins active in the journal context. The site-level default metric defaults to the first available metrics plug-in. If no metric has been chosen for a journal then the site-level main metric will be used for that journal.
According to Alec (Source: Email, 26.02.2013), the journal-level setting will be temporarily placed into the the manager's "Stats & Reports" page of the journal setup and will later have to be migrated into the new tabbed OJS setup pages.
All features specified in this document can be implemented via batch operations through a single (and in one case three) calls of the statistics API. In principle such batch operations could be provided via external data sources. But due to performance reasons, some of the value-added features may require the "main metric" to be cached locally (i.e. in the metrics table). In this case we propose that users should receive a specific warning when selecting such a metric as "main metric" indicating which of the features will not be available. As we don't know right now, whether this is necessary or not (in principle it is not...), such a warning message will not be implemented right now and should be added as needed.
Most-Viewed Articles (II)
The most-viewed article plug-in will show a list of the 10 articles ranking highest for the selected "main metric" throughout a journal. To identify an article's rank we'll sum up the metrics of its galleys excluding the article's abstract (Source: Email Bozana, 06.03.2013). The articles will be presented as title links in a block plug-in.
Journal reader will be able to choose from three time settings: previous month, previous year and "all times". This will define the time span from which statistics will be read. By default "previous month" will be selected.
The most-viewed article block will not be available on site level as the sidebar cannot be easily configured at site level (Source: Email Bozana, 05.03.2013).
This feature uses three separate batch requests to the metrics API. We currently assume that it can therefore be provided for all metric providers, even those that do not use the metrics table. It may be, though, that this is not correct. In case it turns out that the feature cannot be used unless we have locally cached data, it must be adapted to check metrics availability first.
Search Result Ranking (III)
The "main metric" mentioned above can be used as a ranking factor. The "classic" SQL-based OJS search feature does not support ranking. The new Lucene plug-in can be configured to use external data to rank search results, though.
In principle there are two different ways to make Lucene aware of statistics data for ranking purposes:
- The metric data could be submitted to Lucene at indexing time.
- Alternatively metric data can be provided as an "external file field" without re-indexing articles.
As statistics data can change frequently we'd like to avoid having to re-index articles whenever their usage data changes. Having to do so would mean a considerable performance impact. We therefore recommend the second solution.
The recommended solution requires regular generation of a metrics report for all articles. We propose generating such a report on a daily basis via cron job. The cron job would have to execute the following steps:
- Generate a customized metrics report for all articles.
- Save the metrics report as an external solr index file (or copy and update the existing file if it already exists).
- Trigger a "commit" operation to the index so that the new file will be recognized and used.
- Delete the previous file.
In the embedded configuration we'll need a separate cron job to create the file. As this cron job runs locally, we can use the existing rebuildSearchIndex.php script for it. In the central server configuration we can extend the existing "pull" cron job for the same task.
To support the central indexing server use case, the cron job will have to (partially) update rather than overwrite the existing file. We cannot update the file "in place" as it will be locked on Windows machines. We'll rather copy and update the file and delete the previously active file once the commit operation has been issued to Solr which should unlock the previously used file. The file extension will have to be a running number as Solr will always use the last file in alphabetical order.
We recommend implementing this feature as an additional, optional search feature of the Lucene plug-in. This means that another search feature option will be added to the Lucene plug-in's configuration page. Ticking the corresponding configuration check box would activate the feature. If we implement the feature like this then it is probably not necessary to change OJS core. As soon as the feature has been enabled, the Lucene plugin will amend all search queries with an additional boost query that refers to the external field.
The customized metrics report can be easily generated via the Statistics API and provided over HTTP so that it becomes available to remote indexing servers. It contains a list of all unique index object IDs (instId + '-' + articleId) and the corresponding metric boost value, normalized to values between 1.0 (no usage = no boost) and 2.0 (highest usage). The metrics report can be implemented as an operation of the LuceneHandler class and will only be available when the corresponding search feature has been enabled in the plugin.
It has to be decided whether we'd like to use all-time metric data or whether we'd rather restrict usage data to those accrued over the last month or last year. In principle, this decision could be delegated to the journal manager by providing an additional configuration option in the plugin configuration.
An additional option would complicate the user interface, though, and it could not be obvious to the journal manager what this option actually means. We therefore recommend to use a reasonable default and add such an option only if it turns out in practice that there is a real need for it. We recommend using "all-time" metric data for ranking as monthly or yearly data may be systematically distorted in favor of the current edition of a journal which does not seem reasonable.
We currently assume that this feature can be provided through a single batch request to the metrics API. This means that it should be available for all metrics, even those that do not cache metric data locally in the metrics table.
Search Result Ordering (III)
Lucene search supports sorting search results by several sort criteria. We'd like to provide the same functionality for the SQL-based search implementation and include the main metric as one of the sort criteria.
Porting the "sort search results" feature:
As the "classic" OJS search feature is implemented in OJS core this means that we'll have to port code from the Lucene plugin to the
ArticleSearch class in OJS core. Secondly we'll have to extend the
ArticleSearchDAO to support sorting. Sorting must be done before limiting/offsetting results so it cannot be done in
ArticleSearch but must be done in SQL. The SQL in
ArticleSearchDAO::getPhraseResults() already joins published article objects and orders results so that we probably won't see any performance deterioration due to sorting by different criteria.
Sorting by metrics data:
Sorting by metrics data can either be implemented by joining the metrics table directly or by preparing a separate metrics report through the metrics API. The first option would be preferable from a performance point-of-view. Unfortunately some statistics plug-ins will probably not use the metrics table to store aggregate metrics data. To support such plug-ins it we'll instead retrieve metrics data in a batch request through the metrics API. This can still be a performance problem as we have to provide all IDs of articles for which we require metrics. If the remote statistics protocol does not support such a request it would have to retrieve metrics one by one. In this case this use case could only be made available for metrics cached in the local database (i.e. in the metrics table).
In principle sorting could be offered for all locally cached metrics and time windows ("all-time", "last month", "last year"). This would lead to an explosion of sort criteria, though, which would compromise usability of the search interface: If we had three eligible metrics we would get nine (3 times 3) extra sort criteria, etc. We therefore recommend supporting only the "main metric" (if it is cached locally) and let the user choose between two time windows ("all-time" and "current month"). A third time window ("last year") could be added easily if actually required by end users.
All changes required to provide the search result ordering by metrics data must be implemented in OJS core as it should be available for the "classic" SQL based search which is implemented in core.
Most-Read Articles of the same Author (III)
The article (abstract) page should include optionally configurable lists of articles relevant to the currently viewed article. One of these should be a list of all articles by the same author ordered by the "main metric", in descending order. The ordering should be done based on "all-time" metric data. See the reasoning in the search ranking section above.
This feature can be implemented as a generic plug-in via a template hook on the article page. Internally the plugin would be called with the article ID, could then retrieve the corresponding author information and all articles published by the same author.
The author is not a dimension of its own in the metrics table as an article may be written by more than one author, so the author dimension is not additive. This means that we cannot query the author directly through the metrics DAO. As there will usually be a relatively low number of articles per author we can make a single call to the metrics API, though, with an explicit filter on the author's article IDs which we fetch in a separate database query.
As we only need a single batch request to the statistics API we assume that such a request can be fulfilled by all implementors of the API including those not storing metrics data in the local metrics table.
"Similar" Articles (III)
The article abstract page should (optionally) recommend a list of "similar" articles. We propose implementing this feature as a separate generic plugin hooking into the article page template.
To support this use case we recommend implementing the "similar article" search as part of the core OJS search API. Currently such a feature is only available for the Lucene plug-in. This allows us to implement the "similar articles" plugin without having to make it directly aware of specific search implementations. The plugin would call the search API with an article ID which would retrieve similar articles based on the given ID.
To implement similarity search for the current SQL based search implementation we recommend finding similar articles based on subject keywords. We could construct an OR-joined search request with the subject keywords of the article against the subject keyword field of all articles of the same journal (or site-wide if the search query is not restricted to a journal). If the article does not have any subject keywords assigned then an empty result set will be returned.
We recommend ordering the result set by the default ranking score of the search implementation and displaying only the first 10 results directly on the article page. In the case of a Lucene search this means that results can be ranked (among other factors) by the "main metric" as described above. In the case of the SQL-based search, results could still be pre-ordered by the "main metric". This could however place less relevant articles to the top of the list just because they have been used more. This doesn't seem appropriate in this specific case where "similarity" should be the main ranking factor. We therefore propose adding a "see more" link to the bottom of the list which will take the user to the default search interface where more than 10 results can be displayed and (among other search features) sorting by metric will be available.
Integration with the Tag Cloud Plugin (III)
The existing tag cloud plug-in already uses the search API to retrieve articles matching a given keyword. It therefore will automatically rank search results by "main metric" if the Lucene search is activated and ranking by metric has been enabled.
In the case of SQL based search, pre-ordering of results by the "main metric" could be implemented without extra implementation cost via the search API but is not recommended due to the same reasons laid out in the case of the "similar article" feature. Users who wish to re-order results by metric can immediately do so in the search UI after clicking on one of the keywords.
Statistics Reports (PKP/Bruno)
NB: As agreed with Juan and Bruno, this functionality will be implemented by PKP.
Proposal for implementation: On the basis of the PHP input format specification of the front-end API (see above) we can easily define an HTTP GET version of the input protocol. Translating such a protocol one-to-one to a call on the internal API is trivial.
This will allow us to easily define reports which then can be presented in various formats (XML, CSV, HTML, PDF) without having to implement or even think about a heavy report generator front-end. Such a front-end can be implemented at any time if we like but I'd rather not try to re-invent Excel Pivot Tables in OJS.
With an HTTP GET protocol exporting live OLAP data to Excel or other OLAP tools will be extremely easy. Thus data can be flexibly analyzed outside OJS while common predefined reports with dynamic choices (e.g. time) can be implemented in OJS with a light weight front-end or on any page with a simple download/page link.
This gives advanced OJS users nice opportunities for very easy but still powerful definition of custom reports in any supported output format everywhere in OJS or even for inclusion on external web pages. It will also make it trivial to replace existing statistics reports by links to the generic report generator. Loads of duplicate code can thereby be deleted from the code base and cross-metric reports will be available for the first time.
Editors, Authors and Readers Pages (PKP/Juan)
NB: As agree with Juan, this functionality will be implemented by PKP based on the statistics API.


text:
Dateline Zborowek, 2-June-1878 – This marriage announcement was slightly delayed. Maryanna Zasucha, age 38 of Komorow, daughter of Sebastyan & Apolonia (nee Cygan) Zasucha married Walenty Golen, age 23 of Wojcza [Editor: An early cougar], son of Jozef & Maryanna (nee Midorowicz) Golen. This was witnessed by: Toma Zasucha (age 37) & Jozef Plieta.
I am posting this as I am searching for Zasucha in and around Pacanow who may be related to great-great-grandmother Anna Zasucha, who married Marcin/Martin Elijasz of Pacanow. So I am thinking perhaps these Komorow Zasucha of the Zborowek parish may possibly be related.
Here is some miscellanea of the parish of Zborowek – made up of the following villages: Zborowek, Biskupice, Komorow, Orzelec, and Zalesie. Parish Ksiaznice (who records were noted in the 1878 Zborowek as a separate parish-within-a-parish) is made up of the following village(s): Ksiaznice [Editor: ???].
The Ksiaznice Question
Which leads to another question of Stanczyk's. Why are there three parishes in the same vicinity: Pacanow-Ksiaznice-Zborowek. These fine parishes are closely surrounded by Biechow and Beszowa parishes. Can someone from Poland explain to me how this parish arrangement arose? At the very least, Ksiaznice seems excessive even for Poland.
Major Miscellanea
Stanczyk emailed a Kornelia Major of SwietoGen Genealogical Society. I am hoping for a return email. Hence the above marriage record posted. I am also give my great-grandmother's (Aniela Major) info below in hopes there is a family connection between us and you can fill me in on a portion of the family tree (drzewo genealogiczne) or help me with Pacanow church records.
Aniela Major was born (urodziny): 31-July(Lipca)-1866 in Piestrzec, Poland and married Tomasz Leszczynski on 22-October(Padz.)-1885 in Pacanow. Aniela was the daughter of Martin Major of Piestrzec and Katarzyna Ozarowicz. That is sum total of my knowledge of the Major family.
So, proszę, Kornelia Major or any other Major in SwietoGen or elsewhere in the region, email Stanczyk .

subset: commoncrawl


text:
You are here
Traditional Bedrooms For Every Decorating Taste
Traditional design is not a single look, but many
Traditional design is not a single look, but many. When designing a bedroom, it's the go-to style for capturing the nuances of individual tastes. For example, French toile fabric and feminine bedroom decoration are synonymous. But there is more to traditional toile than the pretty reds and blues and fanciful fabrications like balloon shades or puddling bed and window panels. Toile's wide span of colorways means there are palettes appropriate for a more masculine sensibility. And a restrained or tailored application results in the man of the house feeling as comfortable in his bedroom as does his wife.
Toile Bedroom
This showhouse bedroom in the San Francisco Decorator Showcase was designed expressly with a man in mind. Two layers of black-and-ivory toile lined in flannel for weighty, masculine appeal cloak the walls and windows. "I was trying to go in the opposite direction of how toile would typically be used," says designer Michael Burg. The tailored applications are hung from brass hooks attached to the ceiling. Even the Louis XVI-style bed upholstered in taupe mohair and topped with a wool bedcover doesn't pose a "girl cave" threat. Gentlemen, relax. Women, rejoice. As used in this space, traditional toile is a compromise made in design heaven.
Interior design: Michael Burg
Add Architecture to Your Bedroom Design
Choosing the right piece of furniture can make an enormous difference in whether your bedroom feels like a bland box or a stately escape with as much visual intrigue as your home's public spaces. In this bedroom for the San Francisco Decorator Showcase, interior designer Michael Burg included a hefty antique Napoleonic cabinet with an ebony-and-gilt finish for storing books and accessories. The bold black furnishing keeps the room man-friendly (it's a given that women will love it), and the piece's scale and design lift the space from the mundane by adding an architectural gravitas.
Tip: The benefits of black furniture for the bedroom can't be overemphasized. Include a large black cabinet for architectural interest in a room that is lacking; use a black furnishing to anchor a light and airy design; and appease the man of the house with a black furnishing that's a nod to his masculinity.
Interior design: Michael Burg
His and Hers Bedroom
As a his-and-her space, the master bedroom requires some finessing to get the right balance of masculine and feminine so both members of the couple are happy. A black-and-white color palette is a safe bet. Plus, it's one of the more interesting color combos, with the bold, graphic strength of the contrasting colors. This bedroom in a South African home celebrates that country's colonial style, but its popular design components know no boundaries. The big black wrought-iron bed serves as the room's focal point. Cotton bed curtains puddle to the floor and hang loosely at the top for a casual, breezy elegance. Dark wood flooring and dark shutters contrast with a white coffered ceiling. The look is as appropriate for Cleveland or Kansas City as it is for Cape Town. And, for this homeowner at least, it didn't require the services of an interior designer. The key: Keep it simple.
Bedroom Goes Bold in Black and White
Black and white is a favorite color palette of many designers and design editors for one simple reason: It's hard to mess up. This small guest room defies its shoebox shape and lack of architectural embellishment with a graphic palette of black and white. Black and white floor tiles laid on the diagonal get the room pulsating with visual rhythm. Patterned on the bed linens, a splashy modern design of stylized black leaves and vines on a white ground holds its own against the flooring. Even the art dips into the black and white scheme for guest quarters that are lively, much-anticipated destination.
Interior design: Kazumi Yoshida
Luscious Aubergine Bedroom
Aubergine, a complex color between lavender and brown, carries the style statement in this glamorous traditional master bedroom. The tall hotel-style headboard is upholstered in mohair. It creates the illusion of higher ceiling heights in a room that appears squatty due to almost dormer-size windows. Textural interest is provided by glossy fabrics on decorative pillows, the nubby appeal of the bedcover, and the soft mohair of the bench at the foot of the bed—all variations on aubergine. The rich color palette emanated from the Fortuny-style painted silk chandelier.
Interior design: Karen Miller
Girlish Vanity
The bedroom's glamorous style continues to the dressing table, which is skirted in aubergine silk taffeta. An antique mirror flanked by matching hand-painted lamps and a mohair vanity stool centered with the mirror accessorize the table in pleasing symmetrical balance. More opulence is indulged at the windows. Tightly gathered silk curtain panels are underscored by a tailored stairstep valance in a matching fabric.
Interior design: Karen Miller
Bedroom Designed to Touch the Sky
Every room—especially bedrooms, it seems—faces design challenges. In this richly appointed master bedroom, the biggest obstacle to a sophisticated traditional design heavy on the glam were unfortunately small windows. To overcome the windows' weak proportions, designer Karen Miller ingeniously crafted a stairstep valance that fools the eye into thinking the window is taller than it really is. She also mounted the valance directly to the ceiling to increase the heightening effect.
Tip: In a low- or standard-ceiling bedroom, mount window treatments from the ceiling to increase the perception of vertical space.
Interior design: Karen Miller
Dressmaker Details Enrich Bedroom
Now take a step back and look at the bedroom as a whole. Its sum is at least as good as its parts. As beautiful as the mohair headboard is, that's not the end of this bedtime story. Luxury and attention to detail continue all the way to the floor, where a lush skirt skirt fabricated with box pleats skims the carpet. It's traditional style with Hollywood glam.
Interior design: Karen Miller
Scandinavian Style Bedroom
One of traditional design's most popular and enduring styles hails from Scandinavia. The light touch of this 18th-century design style, also known as Gustavian, is ideal for decorating the bedroom. This lilac-painted master bedroom traces its quirky ceiling (really, roofline) contours with white-painted wood, defining the room with charming pastel color and linear simplicity. The only hint of formality is the small lilac-glass-bead chandelier. Even the floors are left raw in their pale natural wood. A French bedcover, a chair upholstered in old linen, and a painted pine table complete the furnishings. The bedroom was designed by the homeowner.
Artfully Abundant Bedroom
San Francisco designer Martha Angus is an art collector extraordinaire, so there was never any doubt she would include favorite pieces in the master bedroom of her Nob Hill home. A painting by Ciao Fonseca hangs above her bed, while a David Hockney print rests on a French chest at the side of the bed. To give the art its due, Martha kept the design calm with a custom bed that's streamlined and crisp, and quiet jute carpet on the floor.
Interior design: Martha Angus
Traditional Bedroom That Can't Be Niched
His bedroom proves his point. Interior designer David L. Smith is hard-pressed to label his decorating style—an artful and unexpected blend of old and new. "I like things crisp and clean. I'm becoming more of a modernist as I get older, but with a little of the old thrown in." Old, as in the 1930s painted screen that hangs above his bed. The funky, faux-valanced screen creates an instant and one-of-a-kind focal point for a room that's a celebration of tailored modernism and Old World curves.
Interior design: David L. Smith and Gary Clark
Designing Beyond the Basic Bedroom
David L. Smith's love of all things decorative means a bedroom that's as compelling as any room in the house. His includes a work area, which is possibly a good excuse to anchor more gorgeous period chairs around a highly stylish glass-top faux bois desk. It's also a grand reason to define the work area with art. His collection ranges from portraits to landscapes, from equestrian to avian art.
Tip: Make your bedroom work for you. Determine your needs, then create different furniture arrangements to address them. Don't skimp on personal collections. Displayed en masse, they are a great way to differentiate one space from another.
Interior design: David L. Smith and Gary Clark
Classic Blue Bedroom
For the master bedroom in her Manhattan apartment, designer Gail Green created a complex neoclassical design in basic blue, a universal favorite. She rolled back the calendar to the 18th century, picking up the motifs and style elements popularized by that periods's influential architect and designer Robert Adam. The room includes neoclassical architectural embellishments, and it also playfully and expertly incorporates Adamesque influences in its well-curated mix of blue-and-white fabrics. Interestingly, this most traditional of bedrooms coexists in an apartment elsewhere enlivened with strong modernist features. "For a decor to be remarkable, you have to be willing to take risks," advises the designer.
Tip: Consider a dark paint for guest room walls for ultimate cocooning. You won't grow tired of it, and neither will your guests.
Interior design: Gail Green
Charming Chocolate Guest Room
Warm chocolate-painted walls spin an inviting cocoon around guests who stay overnight at the New Orleans home of architect Ken Tate and his designer wife, Charme. "Every house needs at least one dark room," she insists. The dark (Benjamin Moore paint) hue in this room is a dramatic foil for bright gold-and-white checked draperies, and for the two abstract paintings by Ken that hang above an antique table. An ebony four-poster bed from Harden contrasts with its snowy white coverlet. An antique Oriental rug brings the palette together.
Tip: Consider a dark paint for guest room walls for ultimate cocooning. You won't grow tired of it, and neither will your guests.
Interior design: Charme Tate
Give Guests a Bedroom Break
When space permits, cozy up a bedroom with comfy seating to facilitate reading, relaxing, TV watching, and conversation. This is especially important in a guest room, the only retreat of their own your overnight visitors may have. The guest room in the home of a Louisiana architect and his designer wife delivers Southern hospitality with a pair of soft-cushioned club chairs covered in an elegant brown-on-white Cowton and Tout toile. Creature comforts like an oversize mirror don't just lend themselves to great design, they serve an essential function. The style is quintessentially traditional, but the warm chocolate walls lift it into the moment.
Tip: Up the visual interest by elevating art to unexpected heights such as above a door. Sure, it breaks the rules, but that's the point.
Bedroom Soothed with Bits of Blue
A restrained traditional style reigns in this master bedroom. It begins with the edited blue-and-white palette. Bits of blue blossom helter-skelter in the space, versus blue bathing the room. This lends the design a clean look with a modern bent. A geometric blue cube pattern covers the bench at the foot of the bed, while the bed's coverlet is tasteful and spare blue stripes coloring a mainly white field. The geometric patterns are reinforced by abstract art (blue) above the mantel. The graphic pattern on the club chairs suggests a rhythm akin to that of the art.
More Bedroom Decorating
Find more design ideas for your bedroom in Dramatic Bed Canopies and Draperies.


text:
A trust is an arrangement under which one person, called a trustee, holds legal title to property for another person, called a beneficiary. You can be the trustee of your own living trust, keeping full control over all property held in trust.
A "living trust" (also called an "inter vivos" trust by lawyers who can't give up Latin) is simply a trust you create while you're alive, rather than one that is created at your death under the terms of your will.
The main advantage of making a living trust is to spare your family the expense and delay of probate court proceedings after your death. But do you really need a trust?
Alaska uses the Uniform Probate Code, which simplifies the probate process, so making a living trust may be more trouble than it saves. In addition, Alaska has a simplified probate process for small estates (under $100,000). If your net worth will be under this amount when you die, the probate process will be straightforward and relatively inexpensive, so you may not need to worry about avoiding it.
Yes, you always need a will. A will provides a backup plan for any property that doesn't make it into your trust. For example, if you acquire new property and don't add it to your trust before you die, that property won't pass under the terms of the trust document. You can use a will to name someone to inherit property that you haven't left to a particular person or entity in your trust.
If you don't have a will, any property that isn't transferred by your living trust or other method (such as joint tenancy) will go to your closest relatives as determined by Alaska state law.
It depends on the kind of trust you create. A simple probate-avoidance living trust has no effect on federal estate tax. However, more complicated living trusts, such as an AB trust, can reduce the federal estate tax bill for people who own a lot of valuable assets. (Most people, though, don't need to worry about federal estate tax because it affects only estates worth more than $5 million.) For more information on when you still might want to use an AB trust to reduce estate taxes, see Nolo's article Tax-Saving AB Trusts.
To make a living trust in Alaska, you:
Nolo's Online Living Trust can create your living trust document for you. Our simple interview asks some questions about you and your property, and based on your responses, our trust document is customized for you and your situation, complying with the laws of your state. Nolo's Online Living Trust is easy to use and thorough -- and you can make changes for a full year following purchase. For more information, see the Online Living Trust FAQ.


text:
Campaigns built using the Kids! @ your library slogan
Library campaigns built on the Kids! @ your library materials. Scroll down to read more detail about these campaigns!
- 1 1. Library Card Campaign at Public Library of Charlotte & Mecklenburg County (NC)
- 2 2. Dayton Metro Library Kids! @ your library Week (OH)
- 3 3. Maricopa County Library District February Family Festival (AZ)
- 4 4. Campaign to Highlight Children's Materials & Services at the Pamunkey Regional Library (VA)
1. Library Card Campaign at Public Library of Charlotte & Mecklenburg County (NC)
The Library Card Campaign at the Public Library of Charlotte and Mecklenburg County used the So Much to See. So Much to Do @ your library theme to engage and energize the Charlotte-Mecklenburg community about making sure every child in the county in grades K through 5 had a library card by January 2007.
The campaign was borne of a desire for extended collaboration between PLCMC and the public and private schools that serve the children in our community. It was our hope that the Library Card Campaign would create greater awareness of the full educational resources of our libraries while also providing students easy access to these resources through their own library card.
It was an easy pitch to the school; they understand that reading is essential to a child's educational success. Then, we learned that only 47% of children in the age range for grades K-5 were signed up with a library card. So we felt ready to step up to the plate and offer assistance on this aspect of education - literacy.
The process of getting the campaign rolling began with a lot of planning. The library's team had to meet with the Charlotte Mecklenburg School System, Mecklenburg Area Catholic Schools and the North Carolina Area Independent Schools to work out a timeline for rolling the program out at each school in the county.
Four steps were built as a way to ensure success by all parties involved:
- Distribution of library card applications specific to this campaign to every child in kindergarten through 5th grade.
- Processing of each child's application and the delivery of the "So Much to See" library card.
- Developing promotional materials and ideas for the campaign were included in a manual and CD distributed to each library and school.
- Recognition included stickers, business incentives, backpack drawing and other incentives provided by the individual schools.
Our main piece of technology used was our library's Web site which included information about the campaign, Bill Harley's song, local business incentives and other details.
The campaign ended with an increase of 26% more students with library cards or 73% of the students in the county. This was an increase of more than 20,000 students. Working together the library and schools enhanced the level of awareness of all that goes on at the library. The slogan of the campaign, "So Much to See. So Much to Do @ your library" implied to everyone that there is just so much going on, you may be missing something.
Nancy Snyder, Project Facilitator, Public Library of Charlotte & Mecklenburg County (NC), Morrison Regional Library
2. Dayton Metro Library Kids! @ your library Week (OH)
Dayton Metro Library conducted our first Kids! @ your library campaign in November 2006, timing it to coincide with Children's Book Week.
Main Library and 21 branches offered special programming that week targeting boys and girls in grades K-5. We wanted it to be "summer reading program-intensive, but only lasting a week".
- Librarians were given copies of a CD with Bill Harley's song on it, as well as the sheet music and lyrics. Many used this in conjunction with programming or promotions for the week.
- While some programs were passive, most were filled with activities and fun such as scavenger hunts, games and puzzles, bookmark contests, costumed character visits (rented locally), and family movie nights. The games we used can be found in the Kids! @ your library toolkit.
- We purchased the ALA Graphics kits featuring the So Much to see. So Much to Do. logos for each branch. Bookmarks from the kit were used at the discretion of the branch; some used them as prizes, some handed them to patrons after programs.
- Several branches used stickers with the logo (created using Avery Labels, sticking them on mini Hershey candy bars) to reward children who visited the library that week.
- We had pencils made that feature our library mascot and new central phone number; these were also distributed to children who visited, or used as a prize.
That week, our library's website was set up to play Bill Harley's song @ your library whenever the page of programming for children was displayed.
To draw children into the library this week, we distributed raffle tickets for prizes, with the drawing held just after the week ended.
- Each branch was given a Children of the Lamp backpack (courtesy of Schoalstic Publishing) that was filled with gift books, AV materials, and other goodies to raffle off.
- Once those winners were determined at the branches, raffle tickets were sent to our Community Relations Department, where they were placed in a tumbler and several grand prize winners were drawn. These system-wide prizes included tickets to Kings Island Amusement Park, a family membership to our local children's musuem, and a movie theater gift card and were paid for by our Friends of the Library.
Over 34,000 flyers were distributed to students through schools in the DML service area. These flyers publicized a schedule of events for the closest branch, a short note to parents about the week, and the raffle ticket for the child. Children who did not receive a flyer via a school were able to receive one at the branch.
We were delighted with the media coverage that week.
- One local television station did extensive coverage, featuring boys and girls doing a reader's theater presentation and the Library Rap (from the Kids! @ your library toolkit) at one branch.
- The Dayton Daily News had a feature column article about the week on top of the shorter listing on the calendar of events page.
- Several local newspapers carried articles about the special events at the library.
- Numerous towns and cities in the DML service area issued proclamations, making it officially Kids @ your library Week in their city/town.
Although attendance numbers remained the same that week, circulation figures were up slightly and we feel it was a success and have been through an evaluation process with the children's librarians. We are in the beginning stages of planning our next Kids! @ your library campaign based on their input and lessons learned!
Letitia (Tish) Wilson, Assistant Director, Youth Services, Dayton Metro Library (OH)
3. Maricopa County Library District February Family Festival (AZ)
In February, 2007 the Maricopa County Library District sponsored a month-long Family Festival to promote the idea that there is So Much to See, So Much to Do @ Your Library throughout Maricopa County.
A. Organizational Background
- The Maricopa County Library District provides library service to all residents of Maricopa County.
- The Library District operates three Regional Libraries, ten Community Libraries and a bookmobile and other outreach services.
- The mission of the Library District is to provide access to a wealth of informational and recreational resources for people of all ages and backgrounds so that they may have the opportunity to expand their horizons through reading and learning with a particular emphasis on early literacy and family programs.
- We participate in a state wide program called "Building a New Generation of Readers" with the goal of assisting parents and caregivers to ensure that children are ready to read when they enter school.
B. Event
We planned a Family Festival to take place in February, 2007 with events that parents and kids could enjoy together using the theme "So Much to Do, So Much to See @ Your Library." We wanted parents to know that taking their kids to the library is one of the best and most important things they can do for their children. This was the largest event that the Library District has organized and attracted families as we from all over the County.
Throughout February, 2007 all our thirteen branch libraries held events that will highlight the role that libraries play in building literacy. We planned three signature programs. Two of those were presented in the majority of our branches.
- Performances of the touring production of "River Rat and Cat" by Childsplay (http://childsplayaz.org/), the Valley's premier theater company for young audiences.
- We sponsored a two-week residency by the Frogtown Mountain Puppeteers, (http://frogtownpuppets.com/) three very brilliant, talented and innovative young siblings from Bar Harbor, Maine. We have found the puppetry is one of the best ways to bring audiences into the library.
- The centerpiece of our programming was a residency by the group Trout Fishing in America (www.troutmusic.com) that include four songwriting workshops for children and culminated with a capstone concert at the Maricopa County Events Center, a large performance venue in the West Valley. We planned the workshops for libraries in the Southeast and North valley to encourage attendance at the concert by families throughout the entire metro area. Trout Fishing in America has been nominated for three Grammy awards for best musical album for children, including the nominations announced on December 7, 2006, for their latest CD "My Best Day".
There was a strong educational component to all of these programs. The programs by these artists stimulated imaginations, increased interest in books and the library, improved language and literacy skills and built self-esteem.
C. Media Coverage
The highlights of our media coverage were a quarter page interview with the two members of Trout Fishing in America that was featured in the Sunday Arts and Entertainment section of the Arizona Republic, the Statewide newspaper. We also received broadcast media coverage on Channel 3's "Good Morning Arizona" program which is the most watched morning program locally. Trout Fishing in America was interviewed and performed in a segment on this program. We received coverage on Radio Disney as well.
D. Campaign Logo
We used the campaign logo in a number of ways:
- Library District's monthly Calendar of Events
In the January 2007 calendar announcing the District's February Family Festival the logo appeared three times: on our ad for the Trout Fishing In America concert, on our ad for the Frogtown Mountain Puppeteers performances, and on our ad for Childsplay's performances of the play, River Rat & Cat
In the February 2007 calendar the logo appeared four times: on the cover of the calendar, on our ad for the Trout Fishing In America concert, on our ad for the Frogtown Mountain Puppeteers performances, and on our ad for Childsplay's performances of the play, River Rat & Cat
- Library District's Web site – the logo was on the special events page promoting the February Family Festival.
- Posters & Bookmarks – the logo was on posters in our libraries and on 15,000 bookmarks distributed at our libraries and other locations.
- Press Releases – the logo was on hundreds of press releases sent out to newspapers, magazines, TV and radio stations promoting the Trout Fishing In America Concert and the other February Family Festival events. The press releases also included the wording, "The Maricopa County Library District is presenting Trout Fishing In America (or the name of another festival event) as part of its February Family Festival – So Much To Do. So Much To See. @ your library".
Tim Wadham, Youth Services Coordinator, Maricopa County Library District (AZ)
4. Campaign to Highlight Children's Materials & Services at the Pamunkey Regional Library (VA)
The Pamunkey Regional Library is promoting library resources for children as a part of our five-year strategic plan.
Beginning in September 2006, each of the 10 branches and bookmobile of the Pumanukey Regional Library System began to use Kids! @ your library materials to highlight library resources for children. We will continue with the campaign through this school year.
- Posters and bookmarks were ordered from ALA Graphics and copies of "Top 10 Things to Do With Children" are visible at each agency.
- Displays are set up at each branch featuring the campaign poster and samples of materials the library has to offer children.
- Programs for children are conducted by part-time staff as a part of this effort. An example program is the Kids! @ your Library program that was held at our Hanover Branch in January 2007. After showing a family movie, parents were welcomed to tour the branch to see resources for children, especially highlighting databases to which the library subscribes.
We have found having the posters and print materials available to use provides an easy opportunity to showcase materials in our libraries. We were especially happy to find the Kids! @ your library materials because while we have a graphics person who doubles duty as a reference librarian. Materials are very beneficial for small and medium-sized libraries who have limited availability to do their own graphics!
Linda Gosnell, Supervising Librarian (Youth Services), Pamunkey Regional Library (VA)


text:
Only hotels in 29226 zip code are listed below. Search for cheap and discount hotel rates in Columbia, SC for your upcoming leisure or conference / group travel. We list the best 29226 hotels and motels so you can review the Columbia hotel list below to find the perfect lodging. Hotels in Richland county and area code 803 are also listed.
How should we direct your call?


text:
Cpc Logistics Jobs Forum
Current Discussions (5) - Start a Discussion
driver in Orange Park, Florida
Updated 70 months ago
What's the company culture at Cpc Logistics? - 1 Reply
Every business has its own style. What is the office environment and culture like at Cpc Logistics? Are people dressed in business casual, jeans...
Kevin in Perth Amboy, New Jersey
Updated 72 months ago
Cpc Logistics Salaries, Bonuses and Benefits. - 1 Reply
What are the average starting salaries, bonuses, benefits and travel requirements like at Cpc Logistics? What do you like best about working at Cpc...
Don in Cary, North Carolina
Updated 112 months ago
How to get a job at Cpc Logistics. - 1 Reply
Do you work at Cpc Logistics? How did you find the job? How did you get that first interview? Any advice for someone trying to get in?
Cpc Logistics News and Happenings.
What do you think - will Cpc Logistics grow fast? Are they expanding their staff? How does Cpc Logistics stack up against the competition?
Cpc Logistics Interview Questions.
It's always hard to know what to expect when going in for that interview -- and preparation can make all the difference. What is the interview...
What's great about where you work? If you could change one thing about your job, what would it be? Got a question? Share the best and worst about what you do and where you work by joining a discussion or starting your own.
Subscribe to this forum as an RSS feed.
» Sign in or create an account to start a discussion.