1. SA TOOLKIT. THE WEBTSS SERVICE A GENERIC INTERFACE FOR ALGORITHMS In this document, we shortly describe a generic interface for algorithms provided in the SA Toolkit. The WebTSS.war WEB service (tested on TomCat 6) distributed with the toolkit is based on that interface The IProcessor interface We can describe an algorithm as a module that transforms a given information set (input) in another information set (output), using perhaps some additional information contained in another information set (context). For performance consideration, it is often useful to limit the size of the output by specifying the expected results. The package ec.tstoolkit.algorithm contains a programming interface (IProcessor) that corresponds exactly to that definition. An implementation of InformationSet, which can contain, in a hierarchical structure, any "named" information (pairs of name-object) is provided in the package ec.tstoolkit.information. That structure allows users to store and retrieve in an efficient way any type of information. We present below the IProcessor interface public interface IProcessor{ InformationSet compute(InformationSet input, InformationSet context, List<String> output); List<String> getInputDictionary(); List<String> getOutputDictionary(); String getName(); String getVersion(); } Beside its main method (compute), a processor must also provide dictionaries that describe the input and the output. That pattern has been applied on Seats, X11 and Terror (SeatsProcessor, X11Processor and TerrorProcessor) in the ec.tstoolkit.algorithm.implementation package. To achieve easy and reusable WEB services, the framework also provide additional classes. The InformationProcessing class describes a single processing; it contains Name Type Description algorithm AlgorithmDescriptor Name and version of the considered algorithm input InformationSet Input query List<String> Items that should be provided in the output. context InformationSet Context of the processing. output InformationSet Result of the processing. That field is empty before the Document1 2. processing metadata MetaData Any additional information on the processing (when, who...) The BulkInformationProcessing class provides a similar description for bulk processing: it replaces the single input-output information sets by a list of such items. Finally, the ProcessingMonitor class, which manages the different processors available in the system, has to find and to call for any (Bulk)InformationProcessing the processor that can compute the document. The ProcessingMonitor class is a singleton. It contains a method to fill any (Bulk)InformationProcessing document. The ec.tss.xml.information package contains all the corresponding classes for xml serialization. Using that facility, the making of WEB services becomes a quasi trivial task. A light RESTFul WEB service is developed in the project WebTSS. That WEB service provides for any algorithm (called xxx) registered in the ProcessingMonitor singleton the following services: Description of the algorithm: o Current version: http://.../WebTSS/xxx/version o Input dictionary: http://.../WebTSS/xxx/input o Output dictionary: http://.../WebTSS/xxx/output Single processing: http://.../WebTSS/xxx/processing [POST] Bulk processing: http://.../WebTSS/xxx/batch [POST] Remarks: InformationSet contain pre-defined entries for errors and for warnings (String[]). After processing, the output (which should always be available) should be inspected to detect possible errors. In the context of pure Java applications, the use of a WEB service for computation may be overkill. Direct call to the underlying algorithm is much more efficient. However, it should be noted that it is the xml serialization that is expansive, not the use of "InformationSet". The light WEB service provided with the framework is quasi-automatically extended when new algorithms are added in the framework (the corresponding processor has just to be registered at the creation of the service). By using well defined dictionaries, we can get very simple solutions for the handling of similar algorithms. For instance, all output of seasonal adjustment procedures should contain entries like "decomposition.trend", "decomposition.sa"... The use of explicit programming interfaces is always safer and more efficient than the use of "weakly typed" informationSet. However that latter solution can lead to much more flexible code. Document1 3. Example: We provide below different solutions for using the Java implementation of Terror. Direct function call, use of the corresponding IProcessor interface and call to the WEB service are successively considered. Terror is applied on a list of time series (TsData objects). 1. Direct function call // creates a "CheckLast" object, from the package ec.tstoolkit.modelling.arima // A default Tramo specification (=rsa5) is used to create a preprocessor. // The score provided by the CheckLast object is similar to the criterion computed in Terror (relative out-of-sample forecast error). CheckLast cl = new CheckLast(new TramoSpecification().build()); List<TsData> items=...; for (TsData s : items) { if ( cl.check(s.getTsData())){ double err = cl.getScore(0); ... } } 2. Use of the generic processor (based on InformationSet). It should be noted that the code for making other algorithms would be very similar. // creates a "TerrorProcessor" object, from the package ec.tstoolkit.algorithm.implementation IProcessor cl = new TerrorProcessor(); List<TsData> items=...; for (TsData s : items) { InformationSet input = new InformationSet(); // fill the input with the series. Default specification is used input.set(IProcessor.SERIES, s); InformationSet output = cl.compute(input, null, null); // checks that the output doesn't contain error messages if (output.get(InformationSet.ERRORS) == null) { // retrieve the scores (which is an array of doubles) double[] scores = output.deepSearch("forecatsts.scores", double[].class); if (scores != null){ double err=scores[0]; ... } } } 3. Use of the light WEB service (WEBTss) through the utility class HttpPox provided in the framework. The code for making other algorithms would also be very similar. // creates an "HttpPox" object, from the package ec.tstoolkit.utilities. // That object will marshal XmlBulkProcessing objects, from the package Document1 4. ec.tss.xml.information // The address of the service must of course be adapted to the local situation HttpPox<XmlBulkProcessing, XmlBulkProcessing> bpox = new HttpPox("http://localhost:8080/WebTSS/terror/batch", XmlBulkProcessing.class, XmlBulkProcessing.class); // creates the dictionary with the requested output. String[] dic = new String[]{"forecasts.scores"}; // creates a bulk processing (package ec.tstoolkit.algorithm) // the output will only contain the scores. BulkInformationProcessing bprocessing = new BulkInformationProcessing( null, dic, null, null); List<TsData> items=...; List<String> itemNames...; // fill the request int icur=0; for (int i=0; i<items.size(); ++i){ InformationSet input = new InformationSet(); input.set(IProcessor.SERIES, items.get(i)); input.set("id", itemNames.get(i)); bprocessing.items.add(new BulkInformationProcessing.Item(input)); } // create the corresponding xml object XmlBulkProcessing xbprocessing = new XmlBulkProcessing(); xbprocessing.copy(bprocessing); // call the WEB service xbprocessing = bpox.processXmlMessage(xbprocessing); // transform the xml object in the actual implementation bprocessing = xbprocessing.create(); // walk through the results for (BulkInformationProcessing.Item item : bprocessing.items) { if (item.output.get(InformationSet.ERRORS) == null) { // retrieve the scores (which is an array of doubles) double[] scores = item.output.deepSearch("forecatsts.scores", double[].class); if (scores != null){ double err=scores[0]; ... } } } Document1