Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-creating-composition-components-jsf-20
Packt
18 Jun 2010
7 min read
Save for later

Creating Composition Components in JSF 2.0

Packt
18 Jun 2010
7 min read
(For more resources on JSF, see here.) A great feature of Facelets consists in composition components (available starting with JSF 2.0). For a better understanding, we will start with a traditional application, and we will compare it with an application that uses composition components. At the end, you will love composition components. Getting ready We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library. How to do it... Let's suppose that we have a list of books, characterized by title, author, and price, and we need to display this list in a table and provide the sorting (ascending/descending) action for each category (see next screenshot): Focusing on this view (not on functionality or backing beans), we will probably write a JSF page like the following (this is the traditional approach): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <h:head> <title> Composition components in JSF 2.0</title> <style type="text/css"> .header { text-align: left; letter-spacing:5px; color:#000099 } .odd { background-color: yellow } .even { background-color: orange } </style> </h:head> <f:view> <h:form> <h:dataTable id="booksId" value="#{booksStore.books}" var="bk" rowClasses="odd, even" headerClass="header"> <!-- book title --> <h:column> <f:facet name="header"> <h:panelGroup> <h:outputText value="Book Title" /> <f:verbatim>[</f:verbatim> <!-- Ascending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="booktitleascid" value="ascending" /> <f:param name="by" value="title"/> <f:param name="order" value="ascending"/> </h:commandLink> <h:outputText value="," /> <!-- Descending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="booktitledescid" value="descending" /> <f:param name="by" value="title"/> <f:param name="order" value="descending"/> </h:commandLink> <f:verbatim>]</f:verbatim> </h:panelGroup> </f:facet> <h:outputText value="#{bk.title}" /> </h:column> <!-- book author --> <h:column> <f:facet name="header"> <h:panelGroup> <h:outputText value="Book Author" /> <f:verbatim>[</f:verbatim> <!-- Ascending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="bookauthorascid" value="ascending" /> <f:param name="by" value="author"/> <f:param name="order" value="ascending"/> </h:commandLink> <h:outputText value="," /> <!-- Descending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="bookauthordescid" value="descending" /> <f:param name="by" value="author"/> <f:param name="order" value="descending"/> </h:commandLink> <f:verbatim>]</f:verbatim> </h:panelGroup></f:facet><h:outputText value="#{bk.author}" /></h:column> <!-- book price --> <h:column> <f:facet name="header"> <h:panelGroup> <h:outputText value="Book Price" /> <f:verbatim>[</f:verbatim> <!-- Ascending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="bookpriceascid" value="ascending" /> <f:param name="by" value="price"/> <f:param name="order" value="ascending"/> </h:commandLink> <h:outputText value="," /> <!-- Descending link --> <h:commandLink action="#{booksStore.sortBooks}"> <h:outputText id="bookpricedescid" value="descending" /> <f:param name="by" value="price"/> <f:param name="order" value="descending"/> </h:commandLink> <f:verbatim>]</f:verbatim> </h:panelGroup> </f:facet> <h:outputText value="#{bk.price}" /> </h:column> </h:dataTable> </h:form> </f:view></html> In addition, we have two backing beans as follows: A Book.java backing bean that maps the book characteristics: package bean;import javax.faces.bean.ManagedBean;import javax.faces.bean.SessionScoped;@ManagedBean@SessionScopedpublic class Book { private String title; private String author; private String price; public Book(String title, String author, String price) { this.title = title; this.author = author; this.price = price; } public Book() { } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }} A BooksStore.java backing bean that defines a list of Book instances and defines a method for sorting the books by title, author, or price is shown next: package bean;import java.util.ArrayList;import java.util.List;import javax.faces.bean.ManagedBean;import javax.faces.bean.SessionScoped;import javax.faces.context.FacesContext;import javax.servlet.http.HttpServletRequest;@ManagedBean@SessionScopedpublic class BooksStore {private List books = new ArrayList();public BooksStore() { books.add(new Book("Learning Website Development with Django", "Ayman Hourieh", "€26.34")); books.add(new Book("Building Websites with Joomla! 1.5", "Hagen Graf", "€29.74")); books.add(new Book("ASP.NET 3.5 Application Architecture and Design", "Vivek Thakur", "€30.99")); books.add(new Book("Drupal 6 Themes", "Ric Shreves", "€26.34")); books.add(new Book("WordPress Theme Design", "Tessa Blakeley Silver", "€26.34")); } public List getBooks() { return books; } public void setBooks(List books) { this.books = books; } public void sortBooks() { FacesContext facesContext = FacesContext.getCurrentInstance(); HttpServletRequest httpServletRequest = (HttpServletRequest) facesContext.getExternalContext().getRequest(); String by = httpServletRequest.getParameter("by"); String order = httpServletRequest.getParameter("order"); System.out.println("The books should be order " + order + " by " + by + "!"); //ordering books }} Obviously, the redundancy of the JSF view is annoying and very primitive. We can fix this by defining a composition component that can be invoked instead of repeating code (the backing beans remain unchanged). The composition component can be created by following a few steps. To start with, we define the composition component page and place it under the /WEB-INF folder: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <ui:composition> <h:column> <f:facet name="header"> <h:panelGroup> <f:verbatim>Book-</f:verbatim> <h:outputText value="${attr}" /> <f:verbatim>[</f:verbatim> <!-- Ascending link --> <h:commandLink action="#{compbean.sortBooks}"> <h:outputText value="ascending" /> <f:param name="by" value="${attr}"/> <f:param name="order" value="ascending"/> </h:commandLink> <h:outputText value="," /> <!-- Descending link --> <h:commandLink action="#{compbean.sortBooks}"> <h:outputText value="descending" /> <f:param name="by" value="${attr}"/> <f:param name="order" value="descending"/> </h:commandLink> <f:verbatim>]</f:verbatim> </h:panelGroup> </f:facet> <h:outputText value="${book[attr]}" /> </h:column> </ui:composition></html> Next, we define a tag library file to map the tag name to the tag source or, in other words, to map the name of the composition component with the composition component source page. In addition, it defines the namespace used to access the tag. This is an XML file that looks like this: <?xml version="1.0"?><!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "facelet-taglib_1_0.dtd"><facelet-taglib> <namespace>http://www.my.facelets.component.com/jsf</namespace> <tag> <tag-name>tableColumn</tag-name> <source>mycomp.xhtml</source> </tag></facelet-taglib>
Read more
  • 0
  • 0
  • 3459

Packt
25 Nov 2014
7 min read
Save for later

Creating an Apache JMeter™ test workbench

Packt
25 Nov 2014
7 min read
This article is written by Colin Henderson, the author of Mastering GeoServer. This article will give you a brief introduction about how to create an Apache JMeter™ test workbench. (For more resources related to this topic, see here.) Before we can get into the nitty-gritty of creating a test workbench for Apache JMeter™, we must download and install it. Apache JMeter™ is a 100 percent Java application, which means that it will run on any platform provided there is a Java 6 or higher runtime environment present. The binaries can be downloaded from http://jmeter.apache.org/download_jmeter.cgi, and at the time of writing, the latest version is 2.11. No installation is required; just download the ZIP file and decompress it to a location you can access from a command-line prompt or shell environment. To launch JMeter on Linux, simply open shell and enter the following command: $ cd <path_to_jmeter>/bin$ ./jmeter To launch JMeter on Windows, simply open a command prompt and enter the following command: C:> cd <path_to_jmeter>\binC:> jmeter After a short time, JMeter GUI should appear, where we can construct our test plan. For ease and convenience, consider setting your system's PATH environment variable to the location of the JMeter bin directory. In future, you will be able to launch JMeter from the command line without having to CD first. The JMeter workbench will open with an empty configuration ready for us to construct our test strategy: The first thing we need to do is give our test plan a name; for now, let's call it GeoServer Stress Test. We can also provide some comments, which is good practice as it will help us remember for what reason we devised the test plan in future. To demonstrate the use of JMeter, we will create a very simple test plan. In this test plan, we will simulate a certain number of users hitting our GeoServer concurrently and requesting maps. To set this up, we first need to add Thread Group to our test plan. In a JMeter test, a thread is equivalent to a user: In the left-hand side menu, we need to right-click on the GeoServer Stress Test node and choose the Add | Threads (Users) | Thread Group menu option. This will add a child node to the test plan that we right-clicked on. The right-hand side panel provides options that we can set for the thread group to control how the user requests are executed. For example, we can name it something meaningful, such as Web Map Requests. In this test, we will simulate 30 users, making map requests over a total duration of 10 minutes, with a 10-second delay between each user starting. The number of users is set by entering a value for Number of Threads; in this case, 30. The Ramp-Up Period option controls the delay in starting each user by specifying the duration in which all the threads must start. So, in our case, we enter a duration of 300 seconds, which means all 30 users will be started by the end of 300 seconds. This equates to a 10-second delay between starting threads (300 / 30 = 10). Finally, we will set a duration for the test to run over by ticking the box for Scheduler, and then specifying a value of 600 seconds for Duration. By specifying a duration value, we override the End Time setting. Next, we need to provide some basic configuration elements for our test. First, we need to set the default parameters for all web requests. Right-click on the Web Map Requests thread group node that we just created, and then navigate to Add | Config Element | User Defined Variables. This will add a new node in which we can specify the default HTTP request parameters for our test: In the right-hand side panel, we can specify any number of variables. We can use these as replacement tokens later when we configure the web requests that will be sent during our test run. In this panel, we specify all the standard WMS query parameters that we don't anticipate changing across requests. Taking this approach is a good practice as it means that we can create a mix of tests using the same values, so if we change one, we don't have to change all the different test elements. To execute requests, we need to add Logic Controller. JMeter contains a lot of different logic controllers, but in this instance, we will use Simple Controller to execute a request. To add the controller, right-click on the Web Map Requests node and navigate to Add | Logic Controller | Simple Controller. A simple controller does not require any configuration; it is merely a container for activities we want to execute. In our case, we want the controller to read some data from our CSV file, and then execute an HTTP request to WMS. To do this, we need to add a CSV dataset configuration. Right-click on the Simple Controller node and navigate to Add | Config Element | CSV Data Set Config. The settings for the CSV data are pretty straightforward. The filename is set to the file that we generated previously, containing the random WMS request properties. The path can be specified as relative or absolute. The Variable Names property is where we specify the structure of the CSV file. The Recycle on EOF option is important as it means that the CSV file will be re-read when the end of the file is reached. Finally, we need to set Sharing mode to All threads to ensure the data can be used across threads. Next, we need to add a delay to our requests to simulate user activity; in this case, we will introduce a small delay of 5 seconds to simulate a user performing a map-pan operation. Right-click on the Simple Controller node, and then navigate to Add | Timer | Constant Timer: Simply specify the value we want the thread to be paused for in milliseconds. Finally, we need to add a JMeter sampler, which is the unit that will actually perform the HTTP request. Right-click on the Simple Controller node and navigate to Add | Sampler | HTTP Request. This will add an HTTP Request sampler to the test plan: There is a lot of information that goes into this panel; however, all it does is construct an HTTP request that the thread will execute. We specify the server name or IP address along with the HTTP method to use. The important part of this panel is the Parameters tab, which is where we need to specify all the WMS request parameters. Notice that we used the tokens that we specified in the CSV Data Set Config and WMS Request Defaults configuration components. We use the ${token_name} token, and JMeter replaces the token with the appropriate value of the referenced variable. We configured our test plan, but before we execute it, we need to add some listeners to the plan. A JMeter listener is the component that will gather the information from all of the test runs that occur. We add listeners by right-clicking on the thread group node and then navigating to the Add | Listeners menu option. A list of available listeners is displayed, and we can select the one we want to add. For our purposes, we will add the Graph Results, Generate Summary Results, Summary Report, and Response Time Graph listeners. Each listener can have its output saved to a datafile for later review. When completed, our test plan structure should look like the following: Before executing the plan, we should save it for use later. Summary In this article, we looked at how Apache JMeter™ can be used to construct and execute test plans to place loads on our servers so that we can analyze the results and gain an understanding of how well our servers perform. Resources for Article: Further resources on this subject: Geo-Spatial Data in Python: Working with Geometry [article] Working with Geo-Spatial Data in Python [article] Getting Started with GeoServer [article]
Read more
  • 0
  • 0
  • 3458

article-image-changing-appearance
Packt
13 Feb 2014
14 min read
Save for later

Changing the Appearance

Packt
13 Feb 2014
14 min read
(For more resources related to this topic, see here.) Controlling appearance An ADF Faces application is a modern web application, so the technology used for controlling the look of the application is Cascading Style Sheets (CSS). The idea behind CSS is that the web page (in HTML) should contain only the structure and not information about appearance. All of the visual definitions must be kept in the style sheet, and the HTML file must refer to the style sheet. This means that the same web page can be made to look completely different by applying a different style sheet to it. The Cascading Style Sheets basics In order to change the appearance of your application, you need to understand some CSS basics. If you have never worked with CSS before, you should start by reading one of the many CSS tutorials available on the Internet. To start with, let's repeat some of the basics of CSS. The CSS layout instructions are written in the form of rules. Each rule is in the following form: selector { property: value; } The selector function identifies which part of the web page the rule applies to, and the property/value pairs define the styling to be applied to the selected parts. For example, the following rule defines that all <h1> elements should be shown in red font: h1 { color: red; } One rule can include multiple selectors separated by commas, and multiple property values separated by semicolons. Therefore, it is also a valid CSS to write the following line of code to get all the <h1>, <h2>, and <h3> tags shown in large, red font: h1, h2, h3 { color: red; font-size: x-large; } If you want to apply a style with more precision than just every level 1 header, you define a style class, which is just a selector starting with a period, as shown in the following line of code: .important { color: red; font-weight: bold } To use this selector in your HTML code, you use the keyword class inside an HTML tag. There are three ways of using a style class. They are as follows: Inside an existing tag: <h1> Inside the special <span> tag to style the text within a paragraph Inside a <div> tag to style a whole paragraph of text Here are examples of all the three ways: <h1 class="important">Important topic</h1>You <span class="important">must</span> remember this.<div class="important">Important tip</div> In theory, you can place your styling information directly in your HTML document using the <style> tag. In practice, however, you usually place your CSS instructions in a separate .css file and refer to it from your HTML file with a <link> tag, as shown in the following line of code: <link href="mystyle.css" rel="stylesheet" type="text/css"> Styling individual components The preceding examples can be applied to HTML elements, but styling can also be applied to JSF components. A plain JSF component could look like the following code with inline styling: <h:outputFormat value="hello" style="color:red;"/> It can also look like the line of code shown using a style class: <h:outputFormat value="hello" styleClass="important"/> ADF components use the inlineStyle attribute instead of just style as shown in the following line of code: <af:outputFormat value="hello" inlineStyle="color:red;"/> The styleClass attribute is the same, as shown in the following line of code: <af:outputFormat value="hello" styleClass="important"/> Of course, you normally won't be setting these attributes in the source code, but will be using the StyleClass and InlineStyle properties in the Property Inspector instead. In both HTML and JSF, you should only use StyleClass so that multiple components can refer to the same style class and will reflect any change made to the style. InlineStyle is rarely used in real-life ADF applications; it adds to the page size (the same styling is sent for every styled element), and it is almost impossible to ensure that every occurrence is changed when the styling requirements change—as they will. Building a style While you are working out the styles you need in your application, you can use the Style section in the JDeveloper Properties window to define the look of your page, as shown in the following screenshot. This section shows six small subtabs with icons for font, background, border/outline, layout, table/list, and media/animation. If you enter or select a value on any of these tabs, this value will be placed into the InlineStyle field as a correctly formatted CSS. When your items look the way you want, copy the value from the InlineStyle field to a style class in your CSS file and set the StyleClass property to point to that class. If the style discussed earlier is the styling you want for a highlighted label, create a section in your CSS file, as shown in the following code: .highlight {background-color:blue;} Then, clear the InlineStyle property and set the StyleClass property to highlight. Once you have placed a style class into your CSS file, you can use it to style the other components in exactly the same way by simply setting the StyleClass property. We'll be building the actual CSS file where you define these style classes. InlineStyle and ContentStyle Some JSF components (for example, outputText) are easy to style—if you set the font color, you'll see it take effect in the JDeveloper design view and in your application, as shown in the following screenshot: Other elements (for example, inputText) are harder to style. For example, if you want to change the background color of the input field, you might try setting the background color, as shown in the following screenshot: You will notice that this did not work the way you reasonably expected—the background behind both the label and the actual input field changes. The reason for this is that an inputText component actually consists of several HTML elements, and an inline style applies to the outermost element. In this case, the outermost element is an HTML <tr> (table row) tag, so the green background color applies to the entire row. To help mitigate this problem, ADF offers another styling option for some components: ContentStyle. If you set this property, ADF tries to apply the style to the content of a component—in the case of an inputText, ContentStyle applies to the actual input field, as shown in the following screenshot: In a similar manner, you can apply styling to the label for an element by setting the LabelStyle property. Unravelling the mysteries of CSS styling As you saw in the Input Text example, ADF components can be quite complex, and it's not always easy to figure out which element to style to achieve the desired result. To be able to see into the complex HTML that ADF builds for you, you need a support tool such as Firebug. Firebug is a Firefox extension that you can download by navigating to Tools | Add-ons from within Firefox, or you can go to http://getfirebug.com. When you have installed Firebug, you see a little Firebug icon to the far right of your Firefox window, as shown in the following screenshot: When you click on the icon to start Firebug, you'll see it take up the lower half of your Firefox browser window. Only run Firebug when you need it Firebug's detailed analysis of every page costs processing power and slows your browser down. Run Firebug only when you need it. Remember to deactivate Firebug, not just hide it. If you click on the Inspect button (with a little blue arrow, second from the left in the Firebug toolbar), you place Firebug in inspect mode. You can now point to any element on a page and see both the HTML element and the style applied to this element, as shown in the following screenshot: In the preceding example, the pointer is placed on the label for an input text, and the Firebug panels show that this element is styled with color: #0000FF. If you scroll down in the right-hand side Style panel, you can see other attributes such as font-family: Tahoma, font-size: 11px, and so on. In order to keep the size of the HTML page smaller so that it loads faster, ADF has abbreviated all the style class names to cryptic short names such as .x10. While you are styling your application, you don't want this abbreviation to happen. To turn it off, you need to open the web.xml file (in your View project under Web Content | WEB-INF). Change to the Overview tab if it is not already shown, and select the Application subtab, as shown in the following screenshot: Under Context Initialization Parameters, add a new parameter, as shown: Name: org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION Value: true When you do this, you'll see the full human-readable style names in Firebug, as shown in the following screenshot: You notice that you now get more readable names such as .af_outputLabel. You might need this information when developing your custom skin. Conditional formatting Similar to many other properties, the style properties do not have to be set to a fixed value—you can also set them to any valid expression written in Expression Language (EL). This can be used to create conditional formatting. In the simplest form, you can use an Expression Language ternary operator, which has the form <boolean expression> ? <value if true > : <value if false>. For example, you could set StyleClass to the following line of code: #{bindings.Job.inputValue eq 'MANAGER' ? 'managerStyle' :  'nonManagerStyle'} The preceding expression means that if the value of the Job attribute is equal to MANAGER, use the managerStyle style class; if not, use the nonManagerStyle style class. Of course, this only works if these two styles exist in your CSS. Skinning overview An ADF skin is a collection of files that together define the look and feel of the application. To a hunter, skinning is the process of removing the skin from an animal, but to an ADF developer it's the process of putting a skin onto an application. All applications have a skin—if you don't change it, an application built with JDeveloper 12c uses some variation of the skyros skin. When you define a custom skin, you must also choose a parent skin among the skins JDeveloper offers. This parent skin will define the look for all the components not explicitly defined in your skin. Skinning capabilities There are a few options to change the style of the individual components through their properties. However, with your own custom ADF skin, you can globally change almost every visual aspect of every instance of a specific component. To see skinning in action, you can go to http://jdevadf.oracle.com/adf-richclient-demo. This site is a demonstration of lots of ADF features and components, and if you choose the Skinning header in the accordion to the right, you are presented with a tree of skinnable components, as shown in the following screenshot: You can click on each component to see a page where you can experiment with various ways of skinning the component. For example, you can select the very common InputText component to see a page with various representations of the input text components. On the left-hand side, you see a number of Style Selectors that are relevant for that component. For each selector, you can check the checkbox to see an example of what the component looks like if you change that selector. In the following example, the af|inputText:disabled::content selector is checked, thus setting its style to color: #00C0C0, as shown in the following screenshot: As you might be able to deduce from the af|inputText:disabled::content style selector, this controls what the content field of the input text component looks like when it is set to disabled—in the demo application, it is set to a bluish color with the color code #00C0C0. The example application shows various values for the selectors but doesn't really explain them. The full documentation of all the selectors can be found online, at http://jdevadf.oracle.com/adf-richclient-demo/docs/skin-selectors.html. If it's not there, search for ADF skinning selectors. On the menu in the demo application, you also find a Skin menu that you can use to select and test all the built-in skins. This application can also be downloaded and run on your own server. It could be found on the ADF download page at http://www.oracle.com/technetwork/developer-tools/adf/downloads/index.html, as shown in the following screenshot: Skinning recommendations If your graphics designer has produced sample screens showing what the application must look like, you need to find out which components you will use to implement the required look and define the look of these components in your skin. If you don't have a detailed guideline from a graphics designer, look for some guidelines in your organization; you probably have web design guidelines for your public-facing website and/or intranet. If you don't have any graphics guidelines, create a skin, as described later in this section, and choose to inherit from the latest skyros skin provided by Oracle. However, don't change anything—leave the CSS file empty. If you are a programmer, you are unlikely to be able to improve on the look that the professional graphics designers at Oracle in Redwood Shores have created. The skinning process The skinning process in ADF consists of the following steps: Create a skin CSS file. Optionally, provide images for your skin. Optionally, create a resource bundle for your skin. Package the skin in an ADF library. Import and use the skin in the application. In JDeveloper 11g Release 1 ( 11.1.1.x) and earlier versions, this was very much a manual process. Fortunately, from 11g Release 2, JDeveloper has a built-in skinning editor. Stand-alone skinning If you are running JDeveloper 11g Release 1, don't despair. Oracle is making a stand-alone skinning editor available, containing the same functionality that is built into the later versions of JDeveloper. You can give this tool to your graphic designers and let them build the skin ADF library without having to give them the complete JDeveloper product. ADF skinning is a huge topic, and Oracle delivers a whole manual that describes skinning in complete detail. This document is called Creating Skins with Oracle ADF Skin Editor and can be found at http://docs.oracle.com/middleware/1212/skineditor/ADFSG. Creating a skin project You should place your skin in a common workspace. If you are using the modular architecture, you create your skin in the application common workspace. If you are using the enterprise architecture, you create your enterprise common skin in the application common workspace and then possibly create application-specific adaptations of that skin in the application common workspaces. The skin should be placed in its own project in the common workspace. Logically, it could be placed in the common UI workspace, but because the skin will often receive many small changes during certain phases of the project, it makes sense to keep it separate. Remember that changing the skin only affects the visual aspects of the application, but changing the page templates could conceivably change the functionality. By keeping the skin in a separate ADF library, you can be sure that you do not need to perform regression testing on the application functionality after deploying a new skin. To create your skin, open the common workspace and navigate to File | New | Project. Choose the ADF ViewController project, give the project the name CommonSkin, and set the package to your application's package prefix followed by .skin (for example, com.dmcsol.xdm.skin).
Read more
  • 0
  • 0
  • 3457

article-image-overview-common-machine-learning-tasks
Packt
14 Sep 2015
29 min read
Save for later

Introducing Bayesian Inference

Packt
14 Sep 2015
29 min read
In this article by Dr. Hari M. Kudovely, the author of Learning Bayesian Models with R, we will look at Bayesian inference in depth. The Bayes theorem is the basis for updating beliefs or model parameter values in Bayesian inference, given the observations. In this article, a more formal treatment of Bayesian inference will be given. To begin with, let us try to understand how uncertainties in a real-world problem are treated in Bayesian approach. (For more resources related to this topic, see here.) Bayesian view of uncertainty The classical or frequentist statistics typically take the view that any physical process-generating data containing noise can be modeled by a stochastic model with fixed values of parameters. The parameter values are learned from the observed data through procedures such as maximum likelihood estimate. The essential idea is to search in the parameter space to find the parameter values that maximize the probability of observing the data seen so far. Neither the uncertainty in the estimation of model parameters from data, nor the uncertainty in the model itself that explains the phenomena under study, is dealt with in a formal way. The Bayesian approach, on the other hand, treats all sources of uncertainty using probabilities. Therefore, neither the model to explain an observed dataset nor its parameters are fixed, but they are treated as uncertain variables. Bayesian inference provides a framework to learn the entire distribution of model parameters, not just the values, which maximize the probability of observing the given data. The learning can come from both the evidence provided by observed data and domain knowledge from experts. There is also a framework to select the best model among the family of models suited to explain a given dataset. Once we have the distribution of model parameters, we can eliminate the effect of uncertainty of parameter estimation in the future values of a random variable predicted using the learned model. This is done by averaging over the model parameter values through marginalization of joint probability distribution. Consider the joint probability distribution of N random variables again: This time, we have added one more term, m, to the argument of the probability distribution, in order to indicate explicitly that the parameters are generated by the model m. Then, according to Bayes theorem, the probability distribution of model parameters conditioned on the observed data  and model m is given by:   Formally, the term on the LHS of the equation  is called posterior probability distribution. The second term appearing in the numerator of RHS, , is called the prior probability distribution. It represents the prior belief about the model parameters, before observing any data, say, from the domain knowledge. Prior distributions can also have parameters and they are called hyperparameters. The term  is the likelihood of model m explaining the observed data. Since , it can be considered as a normalization constant . The preceding equation can be rewritten in an iterative form as follows:   Here,  represents values of observations that are obtained at time step n,  is the marginal parameter distribution updated until time step n - 1, and  is the model parameter distribution updated after seeing the observations  at time step n. Casting Bayes theorem in this iterative form is useful for online learning and it suggests the following: Model parameters can be learned in an iterative way as more and more data or evidence is obtained The posterior distribution estimated using the data seen so far can be treated as a prior model when the next set of observations is obtained Even if no data is available, one could make predictions based on prior distribution created using the domain knowledge alone To make these points clear, let's take a simple illustrative example. Consider the case where one is trying to estimate the distribution of the height of males in a given region. The data used for this example is the height measurement in centimeters obtained from M volunteers sampled randomly from the population. We assume that the heights are distributed according to a normal distribution with the mean  and variance :   As mentioned earlier, in classical statistics, one tries to estimate the values of  and  from observed data. Apart from the best estimate value for each parameter, one could also determine an error term of the estimate. In the Bayesian approach, on the other hand,  and  are also treated as random variables. Let's, for simplicity, assume  is a known constant. Also, let's assume that the prior distribution for  is a normal distribution with (hyper) parameters  and . In this case, the expression for posterior distribution of  is given by:   Here, for convenience, we have used the notation  for . It is a simple exercise to expand the terms in the product and complete the squares in the exponential. The resulting expression for the posterior distribution  is given by:   Here,  represents the sample mean. Though the preceding expression looks complex, it has a very simple interpretation. The posterior distribution is also a normal distribution with the following mean:   The variance is as follows:   The posterior mean is a weighted sum of prior mean  and sample mean . As the sample size M increases, the weight of the sample mean increases and that of the prior decreases. Similarly, posterior precision (inverse of the variance) is the sum of the prior precision  and precision of the sample mean :   As M increases, the contribution of precision from observations (evidence) outweighs that from the prior knowledge. Let's take a concrete example where we consider age distribution with the population mean 5.5 and population standard deviation 0.5. We sample 100 people from this population by using the following R script: >set.seed(100) >age_samples <- rnorm(10000,mean = 5.5,sd=0.5) We can calculate the posterior distribution using the following R function: >age_mean <- function(n){ mu0 <- 5 sd0 <- 1 mus <- mean(age_samples[1:n]) sds <- sd(age_samples[1:n]) mu_n <- (sd0^2/(sd0^2 + sds^2/n)) * mus + (sds^2/n/(sd0^2 + sds^2/n)) * mu0 mu_n } >samp <- c(25,50,100,200,400,500,1000,2000,5000,10000) >mu <- sapply(samp,age_mean,simplify = "array") >plot(samp,mu,type="b",col="blue",ylim=c(5.3,5.7),xlab="no of samples",ylab="estimate of mean") >abline(5.5,0) One can see that as the number of samples increases, the estimated mean asymptotically approaches the population mean. The initial low value is due to the influence of the prior, which is, in this case, 5.0. This simple and intuitive picture of how the prior knowledge and evidence from observations contribute to the overall model parameter estimate holds in any Bayesian inference. The precise mathematical expression for how they combine would be different. Therefore, one could start using a model for prediction with just prior information, either from the domain knowledge or the data collected in the past. Also, as new observations arrive, the model can be updated using the Bayesian scheme. Choosing the right prior distribution In the preceding simple example, we saw that if the likelihood function has the form of a normal distribution, and when the prior distribution is chosen as normal, the posterior also turns out to be a normal distribution. Also, we could get a closed-form analytical expression for the posterior mean. Since the posterior is obtained by multiplying the prior and likelihood functions and normalizing by integration over the parameter variables, the form of the prior distribution has a significant influence on the posterior. This section gives some more details about the different types of prior distributions and guidelines as to which ones to use in a given context. There are different ways of classifying prior distributions in a formal way. One of the approaches is based on how much information a prior provides. In this scheme, the prior distributions are classified as Informative, Weakly Informative, Least Informative, and Non-informative. Here, we take more of a practitioner's approach and illustrate some of the important classes of the prior distributions commonly used in practice. Non-informative priors Let's start with the case where we do not have any prior knowledge about the model parameters. In this case, we want to express complete ignorance about model parameters through a mathematical expression. This is achieved through what are called non-informative priors. For example, in the case of a single random variable x that can take any value between  and , the non-informative prior for its mean   would be the following: Here, the complete ignorance of the parameter value is captured through a uniform distribution function in the parameter space. Note that a uniform distribution is not a proper distribution function since its integral over the domain is not equal to 1; therefore, it is not normalizable. However, one can use an improper distribution function for the prior as long as it is multiplied by the likelihood function; the resulting posterior can be normalized. If the parameter of interest is variance , then by definition it can only take non-negative values. In this case, we transform the variable so that the transformed variable has a uniform probability in the range from  to : It is easy to show, using simple differential calculus, that the corresponding non-informative distribution function in the original variable  would be as follows: Another well-known non-informative prior used in practical applications is the Jeffreys prior, which is named after the British statistician Harold Jeffreys. This prior is invariant under reparametrization of  and is defined as proportional to the square root of the determinant of the Fisher information matrix: Here, it is worth discussing the Fisher information matrix a little bit. If X is a random variable distributed according to , we may like to know how much information observations of X carry about the unknown parameter . This is what the Fisher Information Matrix provides. It is defined as the second moment of the score (first derivative of the logarithm of the likelihood function): Let's take a simple two-dimensional problem to understand the Fisher information matrix and Jeffreys prior. This example is given by Prof. D. Wittman of the University of California. Let's consider two types of food item: buns and hot dogs. Let's assume that generally they are produced in pairs (a hot dog and bun pair), but occasionally hot dogs are also produced independently in a separate process. There are two observables such as the number of hot dogs () and the number of buns (), and two model parameters such as the production rate of pairs () and the production rate of hot dogs alone (). We assume that the uncertainty in the measurements of the counts of these two food products is distributed according to the normal distribution, with variance  and , respectively. In this case, the Fisher Information matrix for this problem would be as follows: In this case, the inverse of the Fisher information matrix would correspond to the covariance matrix: Subjective priors One of the key strengths of Bayesian statistics compared to classical (frequentist) statistics is that the framework allows one to capture subjective beliefs about any random variables. Usually, people will have intuitive feelings about minimum, maximum, mean, and most probable or peak values of a random variable. For example, if one is interested in the distribution of hourly temperatures in winter in a tropical country, then the people who are familiar with tropical climates or climatology experts will have a belief that, in winter, the temperature can go as low as 15°C and as high as 27°C with the most probable temperature value being 23°C. This can be captured as a prior distribution through the Triangle distribution as shown here. The Triangle distribution has three parameters corresponding to a minimum value (a), the most probable value (b), and a maximum value (c). The mean and variance of this distribution are given by:   One can also use a PERT distribution to represent a subjective belief about the minimum, maximum, and most probable value of a random variable. The PERT distribution is a reparametrized Beta distribution, as follows:   Here:     The PERT distribution is commonly used for project completion time analysis, and the name originates from project evaluation and review techniques. Another area where Triangle and PERT distributions are commonly used is in risk modeling. Often, people also have a belief about the relative probabilities of values of a random variable. For example, when studying the distribution of ages in a population such as Japan or some European countries, where there are more old people than young, an expert could give relative weights for the probability of different ages in the populations. This can be captured through a relative distribution containing the following details: Here, min and max represent the minimum and maximum values, {values} represents the set of possible observed values, and {weights} represents their relative weights. For example, in the population age distribution problem, these could be the following: The weights need not have a sum of 1. Conjugate priors If both the prior and posterior distributions are in the same family of distributions, then they are called conjugate distributions and the corresponding prior is called a conjugate prior for the likelihood function. Conjugate priors are very helpful for getting get analytical closed-form expressions for the posterior distribution. In the simple example we considered, we saw that when the noise is distributed according to the normal distribution, choosing a normal prior for the mean resulted in a normal posterior. The following table gives examples of some well-known conjugate pairs: Likelihood function Model parameters Conjugate prior Hyperparameters Binomial   (probability) Beta   Poisson   (rate) Gamma   Categorical   (probability, number of categories) Dirichlet   Univariate normal (known variance )   (mean) Normal   Univariate normal (known mean )   (variance) Inverse Gamma     Hierarchical priors Sometimes, it is useful to define prior distributions for the hyperparameters itself. This is consistent with the Bayesian view that all parameters should be treated as uncertain by using probabilities. These distributions are called hyper-prior distributions. In theory, one can continue this into many levels as a hierarchical model. This is one way of eliciting the optimal prior distributions. For example: is the prior distribution with a hyperparameter . We could define a prior distribution for  through a second set of equations, as follows: Here,  is the hyper-prior distribution for the hyperparameter , parametrized by the hyper-hyper-parameter . One can define a prior distribution for in the same way and continue the process forever. The practical reason for formalizing such models is that, at some level of hierarchy, one can define a uniform prior for the hyper parameters, reflecting complete ignorance about the parameter distribution, and effectively truncate the hierarchy. In practical situations, typically, this is done at the second level. This corresponds to, in the preceding example, using a uniform distribution for . I want to conclude this section by stressing one important point. Though prior distribution has a significant role in Bayesian inference, one need not worry about it too much, as long as the prior chosen is reasonable and consistent with the domain knowledge and evidence seen so far. The reasons are is that, first of all, as we have more evidence, the significance of the prior gets washed out. Secondly, when we use Bayesian models for prediction, we will average over the uncertainty in the estimation of the parameters using the posterior distribution. This averaging is the key ingredient of Bayesian inference and it removes many of the ambiguities in the selection of the right prior. Estimation of posterior distribution So far, we discussed the essential concept behind Bayesian inference and also how to choose a prior distribution. Since one needs to compute the posterior distribution of model parameters before one can use the models for prediction, we discuss this task in this section. Though the Bayesian rule has a very simple-looking form, the computation of posterior distribution in a practically usable way is often very challenging. This is primarily because computation of the normalization constant  involves N-dimensional integrals, when there are N parameters. Even when one uses a conjugate prior, this computation can be very difficult to track analytically or numerically. This was one of the main reasons for not using Bayesian inference for multivariate modeling until recent decades. In this section, we will look at various approximate ways of computing posterior distributions that are used in practice. Maximum a posteriori estimation Maximum a posteriori (MAP) estimation is a point estimation that corresponds to taking the maximum value or mode of the posterior distribution. Though taking a point estimation does not capture the variability in the parameter estimation, it does take into account the effect of prior distribution to some extent when compared to maximum likelihood estimation. MAP estimation is also called poor man's Bayesian inference. From the Bayes rule, we have: Here, for convenience, we have used the notation X for the N-dimensional vector . The last relation follows because the denominator of RHS of Bayes rule is independent of . Compare this with the following maximum likelihood estimate: The difference between the MAP and ML estimate is that, whereas ML finds the mode of the likelihood function, MAP finds the mode of the product of the likelihood function and prior. Laplace approximation We saw that the MAP estimate just finds the maximum value of the posterior distribution. Laplace approximation goes one step further and also computes the local curvature around the maximum up to quadratic terms. This is equivalent to assuming that the posterior distribution is approximately Gaussian (normal) around the maximum. This would be the case if the amount of data were large compared to the number of parameters: M >> N. Here, A is an N x N Hessian matrix obtained by taking the derivative of the log of the posterior distribution: It is straightforward to evaluate the previous expressions at , using the following definition of conditional probability: We can get an expression for P(X|m) from Laplace approximation that looks like the following: In the limit of a large number of samples, one can show that this expression simplifies to the following: The term  is called Bayesian information criterion (BIC) and can be used for model selections or model comparison. This is one of the goodness of fit terms for a statistical model. Another similar criterion that is commonly used is Akaike information criterion (AIC), which is defined by . Now we will discuss how BIC can be used to compare different models for model selection. In the Bayesian framework, two models such as  and  are compared using the Bayes factor. The definition of the Bayes factor  is the ratio of posterior odds to prior odds that is given by: Here, posterior odds is the ratio of posterior probabilities of the two models of the given data and prior odds is the ratio of prior probabilities of the two models, as given in the preceding equation. If , model  is preferred by the data and if , model  is preferred by the data. In reality, it is difficult to compute the Bayes factor because it is difficult to get the precise prior probabilities. It can be shown that, in the large N limit,  can be viewed as a rough approximation to . Monte Carlo simulations The two approximations that we have discussed so far, the MAP and Laplace approximations, are useful when the posterior is a very sharply peaked function about the maximum value. Often, in real-life situations, the posterior will have long tails. This is, for example, the case in e-commerce where the probability of the purchasing of a product by a user has a long tail in the space of all products. So, in many practical situations, both MAP and Laplace approximations fail to give good results. Another approach is to directly sample from the posterior distribution. Monte Carlo simulation is a technique used for sampling from the posterior distribution and is one of the workhorses of Bayesian inference in practical applications. In this section, we will introduce the reader to Markov Chain Monte Carlo (MCMC) simulations and also discuss two common MCMC methods used in practice. As discussed earlier, let  be the set of parameters that we are interested in estimating from the data through posterior distribution. Consider the case of the parameters being discrete, where each parameter has K possible values, that is, . Set up a Markov process with states  and transition probability matrix . The essential idea behind MCMC simulations is that one can choose the transition probabilities in such a way that the steady state distribution of the Markov chain would correspond to the posterior distribution we are interested in. Once this is done, sampling from the Markov chain output, after it has reached a steady state, will give samples of distributed according to the posterior distribution. Now, the question is how to set up the Markov process in such a way that its steady state distribution corresponds to the posterior of interest. There are two well-known methods for this. One is the Metropolis-Hastings algorithm and the second is Gibbs sampling. We will discuss both in some detail here. The Metropolis-Hasting algorithm The Metropolis-Hasting algorithm was one of the first major algorithms proposed for MCMC. It has a very simple concept—something similar to a hill-climbing algorithm in optimization: Let  be the state of the system at time step t. To move the system to another state at time step t + 1, generate a candidate state  by sampling from a proposal distribution . The proposal distribution is chosen in such a way that it is easy to sample from it. Accept the proposal move with the following probability: If it is accepted, = ; if not, . Continue the process until the distribution converges to the steady state. Here,  is the posterior distribution that we want to simulate. Under certain conditions, the preceding update rule will guarantee that, in the large time limit, the Markov process will approach a steady state distributed according to . The intuition behind the Metropolis-Hasting algorithm is simple. The proposal distribution  gives the conditional probability of proposing state  to make a transition in the next time step from the current state . Therefore,  is the probability that the system is currently in state  and would make a transition to state  in the next time step. Similarly,  is the probability that the system is currently in state  and would make a transition to state  in the next time step. If the ratio of these two probabilities is more than 1, accept the move. Alternatively, accept the move only with the probability given by the ratio. Therefore, the Metropolis-Hasting algorithm is like a hill-climbing algorithm where one accepts all the moves that are in the upward direction and accepts moves in the downward direction once in a while with a smaller probability. The downward moves help the system not to get stuck in local minima. Let's revisit the example of estimating the posterior distribution of the mean and variance of the height of people in a population discussed in the introductory section. This time we will estimate the posterior distribution by using the Metropolis-Hasting algorithm. The following lines of R code do this job: >set.seed(100) >mu_t <- 5.5 >sd_t <- 0.5 >age_samples <- rnorm(10000,mean = mu_t,sd = sd_t) >#function to compute log likelihood >loglikelihood <- function(x,mu,sigma){ singlell <- dnorm(x,mean = mu,sd = sigma,log = T) sumll <- sum(singlell) sumll } >#function to compute prior distribution for mean on log scale >d_prior_mu <- function(mu){ dnorm(mu,0,10,log=T) } >#function to compute prior distribution for std dev on log scale >d_prior_sigma <- function(sigma){ dunif(sigma,0,5,log=T) } >#function to compute posterior distribution on log scale >d_posterior <- function(x,mu,sigma){ loglikelihood(x,mu,sigma) + d_prior_mu(mu) + d_prior_sigma(sigma) } >#function to make transition moves tran_move <- function(x,dist = .1){ x + rnorm(1,0,dist) } >num_iter <- 10000 >posterior <- array(dim = c(2,num_iter)) >accepted <- array(dim=num_iter - 1) >theta_posterior <-array(dim=c(2,num_iter)) >values_initial <- list(mu = runif(1,4,8),sigma = runif(1,1,5)) >theta_posterior[1,1] <- values_initial$mu >theta_posterior[2,1] <- values_initial$sigma >for (t in 2:num_iter){ #proposed next values for parameters theta_proposed <- c(tran_move(theta_posterior[1,t-1]) ,tran_move(theta_posterior[2,t-1])) p_proposed <- d_posterior(age_samples,mu = theta_proposed[1] ,sigma = theta_proposed[2]) p_prev <-d_posterior(age_samples,mu = theta_posterior[1,t-1] ,sigma = theta_posterior[2,t-1]) eps <- exp(p_proposed - p_prev) # proposal is accepted if posterior density is higher w/ theta_proposed # if posterior density is not higher, it is accepted with probability eps accept <- rbinom(1,1,prob = min(eps,1)) accepted[t - 1] <- accept if (accept == 1){ theta_posterior[,t] <- theta_proposed } else { theta_posterior[,t] <- theta_posterior[,t-1] } } To plot the resulting posterior distribution, we use the sm package in R: >library(sm) x <- cbind(c(theta_posterior[1,1:num_iter]),c(theta_posterior[2,1:num_iter])) xlim <- c(min(x[,1]),max(x[,1])) ylim <- c(min(x[,2]),max(x[,2])) zlim <- c(0,max(1)) sm.density(x, xlab = "mu",ylab="sigma", zlab = " ",zlim = zlim, xlim = xlim ,ylim = ylim,col="white") title("Posterior density")  The resulting posterior distribution will look like the following figure:   Though the Metropolis-Hasting algorithm is simple to implement for any Bayesian inference problem, in practice it may not be very efficient in many cases. The main reason for this is that, unless one carefully chooses a proposal distribution , there would be too many rejections and it would take a large number of updates to reach the steady state. This is particularly the case when the number of parameters are high. There are various modifications of the basic Metropolis-Hasting algorithms that try to overcome these difficulties. We will briefly describe these when we discuss various R packages for the Metropolis-Hasting algorithm in the following section. R packages for the Metropolis-Hasting algorithm There are several contributed packages in R for MCMC simulation using the Metropolis-Hasting algorithm, and here we describe some popular ones. The mcmc package contributed by Charles J. Geyer and Leif T. Johnson is one of the popular packages in R for MCMC simulations. It has the metrop function for running the basic Metropolis-Hasting algorithm. The metrop function uses a multivariate normal distribution as the proposal distribution. Sometimes, it is useful to make a variable transformation to improve the speed of convergence in MCMC. The mcmc package has a function named morph for doing this. Combining these two, the function morph.metrop first transforms the variable, does a Metropolis on the transformed density, and converts the results back to the original variable. Apart from the mcmc package, two other useful packages in R are MHadaptive contributed by Corey Chivers and the Evolutionary Monte Carlo (EMC) algorithm package by Gopi Goswami. Gibbs sampling As mentioned before, the Metropolis-Hasting algorithm suffers from the drawback of poor convergence, due to too many rejections, if one does not choose a good proposal distribution. To avoid this problem, two physicists Stuart Geman and Donald Geman proposed a new algorithm. This algorithm is called Gibbs sampling and it is named after the famous physicist J W Gibbs. Currently, Gibbs sampling is the workhorse of MCMC for Bayesian inference. Let  be the set of parameters of the model that we wish to estimate: Start with an initial state . At each time step, update the components one by one, by drawing from a distribution conditional on the most recent value of rest of the components:         After N steps, all components of the parameter will be updated. Continue with step 2 until the Markov process converges to a steady state.  Gibbs sampling is a very efficient algorithm since there are no rejections. However, to be able to use Gibbs sampling, the form of the conditional distributions of the posterior distribution should be known. R packages for Gibbs sampling Unfortunately, there are not many contributed general purpose Gibbs sampling packages in R. The gibbs.met package provides two generic functions for performing MCMC in a Naïve way for user-defined target distribution. The first function is gibbs_met. This performs Gibbs sampling with each 1-dimensional distribution sampled by using the Metropolis algorithm, with normal distribution as the proposal distribution. The second function, met_gaussian, updates the whole state with independent normal distribution centered around the previous state. The gibbs.met package is useful for general purpose MCMC on moderate dimensional problems. Apart from the general purpose MCMC packages, there are several packages in R designed to solve a particular type of machine-learning problems. The GibbsACOV package can be used for one-way mixed-effects ANOVA and ANCOVA models. The lda package performs collapsed Gibbs sampling methods for topic (LDA) models. The stocc package fits a spatial occupancy model via Gibbs sampling. The binomlogit package implements an efficient MCMC for Binomial Logit models. Bmk is a package for doing diagnostics of MCMC output. Bayesian Output Analysis Program (BOA) is another similar package. RBugs is an interface of the well-known OpenBUGS MCMC package. The ggmcmc package is a graphical tool for analyzing MCMC simulation. MCMCglm is a package for generalized linear mixed models and BoomSpikeSlab is a package for doing MCMC for Spike and Slab regression. Finally, SamplerCompare is a package (more of a framework) for comparing the performance of various MCMC packages. Variational approximation In the variational approximation scheme, one assumes that the posterior distribution  can be approximated to a factorized form: Note that the factorized form is also a conditional distribution, so each  can have dependence on other s through the conditioned variable X. In other words, this is not a trivial factorization making each parameter independent. The advantage of this factorization is that one can choose more analytically tractable forms of distribution functions . In fact, one can vary the functions  in such a way that it is as close to the true posterior  as possible. This is mathematically formulated as a variational calculus problem, as explained here. Let's use some measures to compute the distance between the two probability distributions, such as  and , where . One of the standard measures of distance between probability distributions is the Kullback-Leibler divergence, or KL-divergence for short. It is defined as follows: The reason why it is called a divergence and not distance is that  is not symmetric with respect to Q and P. One can use the relation  and rewrite the preceding expression as an equation for log P(X): Here: Note that, in the equation for ln P(X), there is no dependence on Q on the LHS. Therefore, maximizing  with respect to Q will minimize , since their sum is a term independent of Q. By choosing analytically tractable functions for Q, one can do this maximization in practice. It will result in both an approximation for the posterior and a lower bound for ln P(X) that is the logarithm of evidence or marginal likelihood, since . Therefore, variational approximation gives us two quantities in one shot. A posterior distribution can be used to make predictions about future observations (as explained in the next section) and a lower bound for evidence can be used for model selection. How does one implement this minimization of KL-divergence in practice? Without going into mathematical details, here we write a final expression for the solution: Here,  implies that the expectation of the logarithm of the joint distribution  is taken over all the parameters  except for . Therefore, the minimization of KL-divergence leads to a set of coupled equations; one for each  needs to be solved self-consistently to obtain the final solution. Though the variational approximation looks very complex mathematically, it has a very simple, intuitive explanation. The posterior distribution of each parameter  is obtained by averaging the log of the joint distribution over all the other variables. This is analogous to the Mean Field theory in physics where, if there are N interacting charged particles, the system can be approximated by saying that each particle is in a constant external field, which is the average of fields produced by all the other particles. We will end this section by mentioning a few R packages for variational approximation. The VBmix package can be used for variational approximation in Bayesian mixture models. A similar package is vbdm used for Bayesian discrete mixture models. The package vbsr is used for variational inference in Spike Regression Regularized Linear Models. Prediction of future observations Once we have the posterior distribution inferred from data using some of the methods described already, it can be used to predict future observations. The probability of observing a value Y, given observed data X, and posterior distribution of parameters  is given by: Note that, in this expression, the likelihood function  is averaged by using the distribution of the parameter given by the posterior . This is, in fact, the core strength of the Bayesian inference. This Bayesian averaging eliminates the uncertainty in estimating the parameter values and makes the prediction more robust. Summary In this article, we covered the basic principles of Bayesian inference. Starting with how uncertainty is treated differently in Bayesian statistics compared to classical statistics, we discussed deeply various components of Bayes' rule. Firstly, we learned the different types of prior distributions and how to choose the right one for your problem. Then we learned the estimation of posterior distribution using techniques such as MAP estimation, Laplace approximation, and MCMC simulations. Resources for Article: Further resources on this subject: Bayesian Network Fundamentals [article] Learning Data Analytics with R and Hadoop [article] First steps with R [article]
Read more
  • 0
  • 0
  • 3455

article-image-unleashing-powers-lumion
Packt
12 Jun 2014
22 min read
Save for later

Unleashing the powers of Lumion

Packt
12 Jun 2014
22 min read
Lumion supports a direct import of SketchUp files, which means that we don't need to use any special format to have our 3D model in Lumion. But if you are working with modeling packages, such as 3ds Max, Maya, and Blender, you need to use a different approach by exporting a COLLADA or FBX file as these two are the best formats to work with Lumion. In particular situations, we may need to use our own animations. You may be aware that we can import basic animations in Lumion from 3D modeling packages such as 3ds Max. Lumion uses the flexibility of shortcuts to improve the control we have in the 3D world. Once we import a 3D model or even if we use a model from the Lumion library, we need to adjust the position, the orientation, and the scale of the 3D model. But keep in mind the importance of organizing your 3D world using layers as well. They are free and they will become very useful when we need to hide some objects to focus our attention on a specific detail or when we use the Hide layer and Show layer effect. At a certain point in our project, we will need to go back and undo a mistake or something that doesn't look as expected. Lumion offers you a very limited undo option. When working with Lumion, and in particular, when organizing our 3D world, and arranging and adjusting the 3D models, we might find the possibility of locking the 3D model's position to be useful. This helps us to avoid selecting and unintentionally moving other, already placed 3D models. From the beginning of our project with Lumion, it is very important for us to organize and categorize our 3D world. Sometimes we may not do this straightaway, and only after importing some 3D models and adding some content from the Lumion library we realize the need to organize our project in a better way. We can use layers and assign the existing 3D models to a new layer. Over the course of a project, it is very common to have certain 3D models updated, and we need to update those 3D models into our Lumion project. This can be a rather daunting task, taking into account that most of the time these updates in the 3D models happen after we have already assigned materials to the imported 3D model. Sometimes during the project, we may face a radical change in a 3D model we have already imported into the Lumion project. The worst scenario is reassigning all the materials to the new 3D model and perhaps relocating to the correct place. However, Lumion has an option to help us with this and to avoid reassigning all the materials or at least not all of them, and the 3D models will stay in exactly the same place. After importing a 3D model we created in our favorite 3D modeling package, it is likely that we want to enhance the look and the environment of the project by using additional 3D models. The lack of detail and content will definitely create a lifeless and dull image or video. Lumion will not only help you learn how to place content from the Lumion library, but also how you can discover what you need. Something indispensable for a smooth workflow in every project are the copy and paste tools. Imagine having to go to the import library to place the 3D model again and assigning a material every single time we need a 3D model. Lumion doesn't have a standard copy and paste tool that we can find in most software, but there is a way to emulate this feature. Lumion will help you copy a 3D model already present in your scene and avoid the trouble of going back to the Lumion library and placing a 3D model already present in your project. Removing or deleting a 3D model is a part of the process of any project. This can be particularly tricky when our 3D world is crowded with 3D models and there is a possibility of selecting and deleting the wrong 3D model. Nevertheless, Lumion does a great job in this area because it protects you from deleting something by mistake. All projects are different, and this typically brings in unique challenges. Sometimes, a building or the environment are really intricate, and this can cause difficulties when we are placing 3D models from the Lumion library. Lumion recognizes surfaces and will avoid intersecting them with any 3D model you want to place in your world. However, there are times when this feature may be in our way and cause difficulties when placing a 3D model. A project needs life, but placing dozens of models one by one is a massive task. Lumion helps us to populate our 3D world by providing the option to place more than one copy at a time. By means of a shortcut, we can place 10 copies of a 3D model. The world we live in is bursting with diversity and variety. Consequently, our eyes are incredible in picking up repetitions. Sometimes, even if we cannot explain why, we know something is wrong with a picture because it doesn't look natural. When we are working on a big project, such repetitions stand out almost immediately. We can use a feature in Lumion that gives us the ability to randomize the size of 3D models while placing them. With more than 2,000 models, we can say that Lumion has everything we need to use in our project. Although Lumion has predefined models, it doesn't mean that we can't modify some basic options. We can modify simple settings such as color and texture, but keep in mind that this doesn't mean we can change these settings in every single 3D model. In almost every project, we have some autonomy to place the 3D models and organize the 3D world. Nevertheless, there are times when we really need more accuracy than one can get with the mouse. Lumion's coordinate system can assist us with this task. Typically, we focus our attention on selecting separate 3D models so that we can make exact and accurate adjustments. Eventually, we will need to do some alterations and modifications to multiple 3D objects. Lumion shows you how you can do this, along with a practical application. While working with selections in Lumion, every time we make a selection and transform the 3D model, we need to choose the correct category. There are particular occasions when we need to select and manipulate 3D models that belong to different categories. Lumion can select 3D models from different categories in one go. Initially, we may find Lumion very restrictive in the way it works with the content placed in our project because we need to select the correct category every time we want to work with a 3D model. However, we can bypass these restrictions by using the option to select and move any 3D model in our world without selecting a category. As mentioned earlier, the world we live is full of diversity and randomness; however, almost on every project, there are some situations when we need to place the content in an orderly way. A quick example is when we need to place garden lamps along a path and they need to be spaced equally. This can be done in Lumion. Lumion is a unique application not only because of what we can do with an incredible quality, but also because we have features that initially may not seem beneficial at all until we work on a project where we see a practical application. One example is when we need to align the orientations of different 3D models, Lumion shows not only how to use it, but also how to apply it in a practical situation. While populating and arranging our project, there are times when a snapping tool comes in handy. We can always use the move and height tools to place the 3D model at the top or next to another 3D model, but Lumion allow us to snap multiple 3D models to the same position in an easy way. While placing content in our project, we are usually concerned about the location of the 3D model. However, later we realize that our project is too uniform, and this is easily spotted with plants, trees, flowers, and other objects. Instead of selecting an individual 3D model and manually rotating, relocating, and rescaling it to bring some variety to our project, Lumion helps us out with a fantastic feature to randomize the orientation, position, and scale of the 3D models. Even in the most perfect project, we can find variations in the terrains and in the building, it's natural that we find inclined surfaces. Rotate on model is a feature in Lumion that allows us to snap to the surface of other 3D models when we are moving a 3D model. We can use this to adjust a car on a slope or a book on a chair. While changing the 3D model's rotation, we can see that when the 3D model is getting closer to the 90 degree angle, it will snap automatically. This is fine, perhaps, in most cases, but there are times when we need to do some precise adjustments and this option can be helpful in our way. Lumion deactivates this feature temporarily. An initial tactic to sculpt and shape the terrain is to use the terrain brushes available with Lumion. Lumion is not an application like ZBrush, but it does well with the brushes provided to sculpt the terrain, and they are not difficult to master. Lumion explains how we can use them and some practical applications in real projects. We know how to use the five brushes to sculpt the terrain and the different results of each one of them. However, we are not limited to the standard values used in each brush because Lumion allows us to change two settings to help us sculpt the terrain. This control is useful when we need to add details at a small or large scale. Some projects don't require any specific terrain from us, but at the same time, we don't want to use a flat terrain. In the Terrain menu, we can find some tools that help us to quickly create mountains and modify other characteristics of our project. When we start a new project in Lumion, we can start using nine different presets. They sort of work as a shortcut to help us get the appearance we want for our project. Most of the time, we may use the Grass preset, but that doesn't mean we get stuck with the landscape presented. We know how we can sculpt the terrain, but we can do more than that in Lumion and see how we can completely change the aspect of the landscape. Although we have 20 presets to entirely change the look of the landscape, this doesn't mean that we cannot change any settings and actually paint the landscape. Lumion explores the Paint submenu and shows how we can use Lumion's textures to paint and change the landscape completely. Perhaps you don't want the trouble of sculpting the terrain using the tools offered in Lumion. Truth be told, in some situations, it is easier and more productive to model the terrain outside Lumion and import that terrain along with the building. Lumion has fantastic material that blends the terrain we imported with the landscape. Another solution to create accurate terrains is by means of a heightmap. A heightmap is a texture with stored values that can be used, in this case, by Lumion that translates this 2D information into a 3D terrain. Lumion will help you to see how you can import a heightmap and save the terrain you created in Lumion as a heightmap file. It is remarkable how little things, such as defining the Sun's direction, have the most considerable amount of impact on a project. Throughout the production process, we may need to adjust the Sun's direction to have a clear view of the project; however, in due course, we will get to a point where we will need to define the final orientation that we are going to use to produce a still image or a movie. Setting up the Sun's direction and height is one of the simplest tasks in Lumion; however, by only using the Weather menu, we can start feeling that there is a lack of control over these settings. Fear not though! Lumion offers an effect that provides assistance to control the Sun in a way that can make all the difference when producing a video. Lumion will help you comprehend not only how you can modify the settings for the Sun, but will also provide you with a practical example of how you can apply this feature in any project. A shadow can be defined as an area that is not or is only partially illuminated because an object is obstructing its source of illumination. It is true that we don't think that shadows are important and essential elements to create a good-looking scenario, but without them our project will be dull. Lumion is going to help us use the Shadow effect to tweak and correct the shadows in order to meet our requirements and the finishing look we want to accomplish. An additional aspect connected to the shadows in Lumion, and it happens in the real world too, is the influence of the sky over shadows. Taking a look at the shadows in any project, you can easily realize how a sunset or a midday scene can transform the color of the shadow. Lumion will show how to control and change the influence that skylight has on shadows. We have been working entirely with hard shadows. The Sun in our 3D world can produce these hard shadows, and they are called by this name because they have strong and well-defined edges with less transition between illumination and the shadow. Soft shadows can be produced by the Sun in certain circumstances, and the sky, likewise, can create these diffused shadows with soft edges. We can apply soft shadows to our project to enrich the final look. So far, we have been looking at how we can use the Weather menu to create an enjoyable environment for our exterior scenes. Lumion is also capable of producing beautiful interior scenes, but we need to work a little bit with the interior illumination before we can produce something that is presentable and eye-catching. For interior scenes, we can use the Global Illumination effect to improve the illumination that is either provided by the Sun or some artificial source of illumination. We can improve the interior look and illumination using Global Illumination. An element that can bring an extra touch to the final movie are the clouds. This is a component that does not always cross our mind when trying to attain a good-looking and realistic movie. Lumion provides us with a lot of freedom not only to change the appearance of the clouds, but also to animate and even create volume clouds to bring this fine-tuning to a different dimension. Fog is a natural phenomenon that can be added to our project, and it can really change a scene dramatically. With it, we can make a scene more mysterious or reproduce the haze where dust, smoke, and other dry particles obscure the clarity of the sky. With the Fog effect, we can achieve this and much more. The fact that we can add rain and snow, as easy as reading this sentence, really proves that Lumion is a powerful and versatile application. Adding rain or snow is something that we can easily achieve by adding two effects in the Photo or Movie mode. Lumion by default uses wind in any project you start. Once you add the first trees, you can see how they slowly move showing the effect of the wind. We can control the wind using the, yes you are right, the Foliage Wind effect. Another option to control the Sun is using a new feature introduced in Lumion Version 4. This option, that we can find under the Effects label, is called Sun study. It is an amazing feature that allows us to select any point on the planet and mimic the Sun in that location. However, there is much more that we can do with this effect. Lumion has more than 500 materials on hand and generally this is more than adequate. Still, Lumion is a very flexible application, and for this reason, you are not fixed with just these materials. We have the opportunity to use our own textures to create other materials. Lumion is not going to show you all the settings that you can use to tweak the material; instead, we are going to focus on how we can replace and adjust an outside texture. Making a 3D model invisible or hiding surfaces from our 3D model is something that we don't anticipate to do in every project. However, there are times when the Invisible material can be very handy, and Lumion demonstrates not only how to apply it, but also some specific situations that we may consider while using this material. Glass is essential in any project we work. From the glass in a complex window to a simple cup made of glass, this material has a deep impact on a still image and even more on a movie, helping us capture the light and reflections of the environment. Lumion has a glass material that can be used to create some of these materials. The Glass material can be manipulated to get a more realistic look. During the production, it is expected that we save the materials applied to the 3D models. This should be done for precaution purposes, in case something goes wrong or when we need to go back and forth with materials, without having to lose any settings. Lumion has an option to save the materials you applied to a 3D model and later on load them again, if necessary. There is another feature that Lumion is going to show you which will give you a chance to save a single material instead of material sets. There are different ways in which we can add water to our project. We can create an ocean as easily as reading this sentence, and the same is true when we need to add a body of water or create a swimming pool. However, what if we want to create a fountain? Let's go even further: can we create a river? Lumion will teach you how easy is to create a streaming water effect. Another beautiful and eye-catching effect is when we have glowing materials in our project. From light bulbs to TV screens, we can add an extra touch to our scene by using the Standard material to create this glow effect. Lumion will teach you not only how to add this glow, but also how you can use textures to produce interesting effects. After adding trees, bushes, and other plants, the next thing you should add to the project is some grass. Prior to Lumion Version 4, you had to be satisfied with the terrain's texture. We can also import some grass, though, the project would become very heavy. You can also add some grass from the Lumion library and adjust that grass in the best way possible. Now, Lumion provides an option to use realistic grass, bringing that whoa factor. Each material has a certain amount of reflection, and this is a setting that we can adjust in almost every material that we can find in Lumion. Taking into account that Lumion is a real-time application, it is natural that in some cases, the reflections don't meet our requirements in terms of accuracy. Lumion has an effect that we can apply to surfaces in our 3D model to improve these reflections. While applying and tweaking materials, you can cross a section in your 3D model where you can easily see some flickering. Although this should be avoided, there is an inbuilt setting in every Lumion material to correct this problem. Fire is a special effect that is accessible in Lumion and is one of those elements that can bring an ordinary scene to life. We may have a living room that per se is excellent with all the materials and light, but when we add fire to the fireplace, it completely transforms the room into a warm, comfortable, and welcoming living room. Alternatively, consider how the same living room can be changed to introduce a romantic scene when illuminated with candles and a fireplace. Lumion is aimed to help you apply fire and control it using the Edit properties menu. In addition to the solid and liquid elements in Lumion, we can find elements that we could label as non-solid. Lumion has a special section for these elements, opening with the smoke, passing all the way through dust, and then finishing with fog and water vapor. How we can place these elements in our project and a realistic application of some of them is what Lumion will teach you. Fountains have their distinctive place in Lumion, and there is a tab dedicated to different categories of fountains. We can separate this tab into two parts: standard fountains and fountains produced by a waterspray emitter. Lumion is aimed to show you where to find these fountains, how to place them in the scene, and also provide you with some useful applications. Falling leaves are an enjoyable extra touch that can improve our still image or movie. Nevertheless, like the preceding special effects, this one needs to be used in the correct amount. Too much can ruin the scene, making the viewer focus more on leaves passing through the screen than actually focus on the 3D model. We can add text to a movie or a still image using the Titles effect, but in some circumstances, we need a text element with some more flexibility. Sometimes, when working on a presentation of a project, we are required to show some additional information; this can be easily achieved using this fantastic feature available in Lumion. We can add text to our project in the Build mode. A clip plane is an object that can be added to a scene and later used in the Movie mode, and it can be animated to produce a kind of reveling effect. Initially, it may seem a little bit confusing, you will understand how to apply it to your scene and animate this plane. It is time to move from special effects, such as fire, smoke, and water that we can add to the scene and move towards effects that we can apply in both the Movie and Photo modes. Lumion gives you an overview of how general effects work, how you can stack them in either the Movie or Photo mode, and how you can control them. It is logical that all the effects available in Lumion are applied using either the Movie or Photo mode. The reason for this is that if all those effects were applied to the Build mode, they would have a massive impact on the performance of the viewport, slowing down our workflow. However, Lumion likes to provide you with the freedom needed to produce the best result possible, and in some situations, it could be useful to check the effects in the Build mode. Bloom is the halo effect caused principally by bright lights in the scene. In real world, the camera lenses we use can never focus perfectly, but this is not a problem under normal conditions. However, when there is an intensely bright light in the scene, these imperfections are perceptible and visible, and as a consequence, in the photo that we would shoot, the bright light will appear to bleed beyond its usual borders. Purple fringing, distortion, and blurred edges are a combination of errors called chromatic aberration. A simple explanation is that chromatic aberration happens when there is a failure on the part of lens to focus or bring all the wavelengths of colors to the same focal plane. As light travels through this lens, the different colors travel at different speeds and go to different places on the camera's sensor. With 3D cameras, this doesn't happen, but we can add chromatic aberration to our image or video, giving an extra touch of realism. The expression "color correction" has a fair number of different meanings. However, generally speaking, we can say that it is a means to repair problems with the color, and we do that by changing the color of a pixel to another color or by tweaking other settings. In Lumion, this means that we can use color correction to either achieve a certain look or to enhance the overall aspect and mood of an image or a movie. We can use this effect in Lumion and apply a few tips to help us not only to correct the color, but also perform some color grading.
Read more
  • 0
  • 0
  • 3454

article-image-creating-java-ee-applications
Packt
24 Oct 2014
16 min read
Save for later

Creating Java EE Applications

Packt
24 Oct 2014
16 min read
In this article by Grant Shipley author of Learning OpenShift we are going to learn how to use OpenShift in order to create and deploy Java-EE-based applications using the JBoss Enterprise Application Platform (EAP) application server. To illustrate and learn the concepts of Java EE, we are going to create an application that displays an interactive map that contains all of the major league baseball parks in the United States. We will start by covering some background information on the Java EE framework and then introduce each part of the sample application. The process for learning how to create the sample application, named mlbparks, will be started by creating the JBoss EAP container, then adding a database, creating the web services, and lastly, creating the responsive map UI. (For more resources related to this topic, see here.) Evolution of Java EE I can't think of a single programming language other than Java that has so many fans while at the same time has a large community of developers that profess their hatred towards it. The bad reputation that Java has can largely be attributed to early promises made by the community when the language was first released and then not being able to fulfill these promises. Developers were told that we would be able to write once and run anywhere, but we quickly found out that this meant that we could write once and then debug on every platform. Java was also perceived to consume more memory than required and was accused of being overly verbose by relying heavily on XML configuration files. Another problem the language had was not being able to focus on and excel at one particular task. We used Java to create thick client applications, applets that could be downloaded via a web browser, embedded applications, web applications, and so on. Having Java available as a tool that completes most projects was a great thing, but the implementation for each project was often confusing. For example, let's examine the history of the GUI development using the Java programming language. When the language was first introduced, it included an API called the Abstract Window Toolkit (AWT) that was essentially a Java wrapper around native UI components supplied by the operating system. When Java 1.2 was released, the AWT implementation was deprecated in the favor of the Swing API that contained GUI elements written in 100 percent Java. By this time, a lot of developers were quickly growing frustrated with the available APIs and a new toolkit called the Standard Widget Toolkit (SWT) was developed to create another UI toolkit for Java. SWT was developed at IBM and is the windowing toolkit in use by the Eclipse IDE and is considered by most to be the superior toolkit that can be used when creating applications. As you can see, rapid changes in the core functionality of the language coupled with the refusal of some vendors to ship the JRE as part of the operating system left a bad taste in most developers' mouths. Another reason why developers began switching from Java to more attractive programming languages was the implementation of Enterprise JavaBeans (EJB). The first Java EE release occurred in December, 1999, and the Java community is just now beginning to recover from the complexity introduced by the language in order to create applications. If you were able to escape creating applications using early EJBs, consider yourself one of the lucky ones, as many of your fellow developers were consumed by implementing large-scale systems using this new technology. It wasn't fun; trust me. I was there and experienced it firsthand. When developers began abandoning Java EE, they seemed to go in one of two directions. Developers who understood that the Java language itself was quite beautiful and useful adopted the Spring Framework methodology of having enterprise grade features while sticking with a Plain Old Java Object (POJO) implementation. Other developers were wooed away by languages that were considered more modern, such as Ruby and the popular Rails framework. While the rise in popularity of both Ruby and Spring was happening, the team behind Java EE continued to improve and innovate, which resulted in the creation of a new implementation that is both easy to use and develop with. I am happy to report that if you haven't taken a look at Java EE in the last few years, now is the time to do so. Working with the language after a long hiatus has been a rewarding and pleasurable experience. Introducing the sample application For the remainder of this article, we are going to develop an application called mlbparks that displays a map of the United States with a pin on the map representing the location of each major league baseball stadium. The requirements for the application are as follows: A single map that a user can zoom in and out of As the user moves the map around, the map must be updated with all baseball stadiums that are located in the shown area The location of the stadiums must be searchable based on map coordinates that are passed to the REST-based API The data should be transferred in the JSON format The web application must be responsive so that it is displayed correctly regardless of the resolution of the browser When a stadium is listed on the map, the user should be able to click on the stadium to view details about the associated team The end state application will look like the following screenshot: The user will also be able to zoom in on a specific location by double-clicking on the map or by clicking on the + zoom button in the top-left corner of the application. For example, if a user zooms the map in to the Phoenix, Arizona area of the United States, they will be able to see the information for the Arizona Diamondbacks stadium as shown in the following screenshot: To view this sample application running live, open your browser and type http://mlbparks-packt.rhcloud.com. Now that we have our requirements and know what the end result should look like, let's start creating our application. Creating a JBoss EAP application For the sample application that we are going to develop as part of this article, we are going to take advantage of the JBoss EAP application server that is available on the OpenShift platform. The JBoss EAP application server is a fully tested, stable, and supported platform for deploying mission-critical applications. Some developers prefer to use the open source community application server from JBoss called WildFly. Keep in mind when choosing WildFly over EAP that it only comes with community-based support and is a bleeding edge application server. To get started with building the mlbparks application, the first thing we need to do is create a gear that contains the cartridge for our JBoss EAP runtime. For this, we are going to use the RHC tools. Open up your terminal application and enter in the following command: $ rhc app create mlbparks jbosseap-6 Once the previous command is executed, you should see the following output: Application Options ------------------- Domain:     yourDomainName Cartridges: jbosseap-6 (addtl. costs may apply) Gear Size: default Scaling:   no Creating application 'mlbparks' ... done Waiting for your DNS name to be available ... done Cloning into 'mlbparks'... Your application 'mlbparks' is now available. URL:       http://mlbparks-yourDomainName.rhcloud.com/ SSH to:     5311180f500446f54a0003bb@mlbparks-yourDomainName.rhcloud.com Git remote: ssh://5311180f500446f54a0003bb@mlbparks-yourDomainName.rhcloud.com/~/git/mlbparks.git/ Cloned to: /home/gshipley/code/mlbparks  Run 'rhc show-app mlbparks' for more details about your app. If you have a paid subscription to OpenShift Online, you might want to consider using a medium- or large-size gear to host your Java-EE-based applications. To create this application using a medium-size gear, use the following command: $ rhc app create mlbparks jbosseap-6 -g medium Adding database support to the application Now that our application gear has been created, the next thing we want to do is embed a database cartridge that will hold the information about the baseball stadiums we want to track. Given that we are going to develop an application that doesn't require referential integrity but provides a REST-based API that will return JSON, it makes sense to use MongoDB as our database. MongoDB is arguably the most popular NoSQL database available today. The company behind the database, MongoDB, offers paid subscriptions and support plans for production deployments. For more information on this popular NoSQL database, visit www.mongodb.com. Run the following command to embed a database into our existing mlbparks OpenShift gear: $ rhc cartridge add mongodb-2.4 -a mlbparks Once the preceding command is executed and the database has been added to your application, you will see the following information on the screen that contains the username and password for the database: Adding mongodb-2.4 to application 'mlbparks' ... done  mongodb-2.4 (MongoDB 2.4) ------------------------- Gears:         Located with jbosseap-6 Connection URL: mongodb://$OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/ Database Name: mlbparks Password:       q_6eZ22-fraN Username:       admin MongoDB 2.4 database added. Please make note of these credentials:    Root User:     admin    Root Password: yourPassword    Database Name: mlbparks Connection URL: mongodb://$OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/ Importing the MLB stadiums into the database Now that we have our application gear created and our database added, we need to populate the database with the information about the stadiums that we are going to place on the map. The data is provided as a JSON document and contains the following information: The name of the baseball team The total payroll for the team The location of the stadium represented with the longitude and latitude The name of the stadium The name of the city where the stadium is located The league the baseball club belongs to (national or American) The year the data is relevant for All of the players on the roster including their position and salary A sample for the Arizona Diamondbacks looks like the following line of code: {   "name":"Diamondbacks",   "payroll":89000000,   "coordinates":[     -112.066662,     33.444799   ], "ballpark":"Chase Field",   "city":"Phoenix",   "league":"National League", "year":"2013",   "players":[     {       "name":"Miguel Montero", "position":"Catcher",       "salary":10000000     }, ………… ]} In order to import the preceding data, we are going to use the SSH command. To get started with the import, SSH into your OpenShift gear for the mlbparks application by issuing the following command in your terminal prompt: $ rhc app ssh mlbparks Once we are connected to the remote gear, we need to download the JSON file and store it in the /tmp directory of our gear. To complete these steps, use the following commands on your remote gear: $ cd /tmp $ wget https://raw.github.com/gshipley/mlbparks/master/mlbparks.json Wget is a software package that is available on most Linux-based operating systems in order to retrieve files using HTTP, HTTPS, or FTP. Once the file has completed downloading, take a quick look at the contents using your favorite text editor in order to get familiar with the structure of the document. When you are comfortable with the data that we are going to import into the database, execute the following command on the remote gear to populate MongoDB with the JSON documents: $ mongoimport --jsonArray -d $OPENSHIFT_APP_NAME -c teams --type json --file /tmp/mlbparks.json -h $OPENSHIFT_MONGODB_DB_HOST --port $OPENSHIFT_MONGODB_DB_PORT -u $OPENSHIFT_MONGODB_DB_USERNAME -p $OPENSHIFT_MONGODB_DB_PASSWORD If the command was executed successfully, you should see the following output on the screen: connected to: 127.7.150.130:27017 Fri Feb 28 20:57:24.125 check 9 30 Fri Feb 28 20:57:24.126 imported 30 objects What just happened? To understand this, we need to break the command we issued into smaller chunks, as detailed in the following table: Command/argument Description mongoimport This command is provided by MongoDB to allow users to import data into a database. --jsonArray This specifies that we are going to import an array of JSON documents. -d $OPENSHIFT_APP_NAME Specifies the database that we are going to import the data into the database. We are using a system environment variable to use the database that was created by default when we embedded the database cartridge in our application. -c teams This defines the collection to which we want to import the data. If the collection does not exist, it will be created. --type json This specifies the type of file we are going to import. --file /tmp/mlbparks.json This specifies the full path and name of the file that we are going to import into the database. -h $OPENSHIFT_MONGODB_DB_HOST This specifies the host of the MongoDB server. --port $OPENSHIFT_MONGODB_DB_PORT This specifies the port of the MongoDB server. -u $OPENSHIFT_MONGODB_DB_USERNAME This specifies the username to be used to be authenticated to the database. -p $OPENSHIFT_MONGODB_DB_PASSWORD This specifies the password to be authenticated to the database. To verify that data was loaded properly, you can use the following command that will print out the number of documents in the teams collections of the mlbparks database: $ mongo -quiet $OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/$OPENSHIFT_APP_NAME -u $OPENSHIFT_MONGODB_DB_USERNAME -p $OPENSHIFT_MONGODB_DB_PASSWORD --eval "db.teams.count()" The result should be 30. Lastly, we need to create a 2d index on the teams collection to ensure that we can perform spatial queries on the data. Geospatial queries are what allow us to search for specific documents that fall within a given location as provided by the latitude and longitude parameters. To add the 2d index to the teams collections, enter the following command on the remote gear: $ mongo $OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/$OPENSHIFT_APP_NAME --eval 'db.teams.ensureIndex( { coordinates : "2d" } );' Adding database support to our Java application The next step in creating the mlbparks application is adding the MongoDB driver dependency to our application. OpenShift Online supports the popular Apache Maven build system as the default way of compiling the source code and resolving dependencies. Maven was originally created to simplify the build process by allowing developers to specify specific JARs that their application depends on. This alleviates the bad practice of checking JAR files into the source code repository and allows a way to share JARs across several projects. This is accomplished via a pom.xml file that contains configuration items and dependency information for the project. In order to add the dependency for the MongoDB client to our mlbparks applications, we need to modify the pom.xml file that is in the root directory of the Git repository. The Git repository was cloned to our local machine during the application's creation step that we performed earlier in this article. Open up your favorite text editor and modify the pom.xml file to include the following lines of code in the <dependencies> block: <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.9.1</version> </dependency> Once you have added the dependency, commit the changes to your local repository by using the following command: $ git commit -am "added MongoDB dependency" Finally, let's push the change to our Java application to include the MongoDB database drivers using the git push command: $ git push The first time the Maven build system builds the application, it downloads all the dependencies for the application and then caches them. Because of this, the first build will always that a bit longer than any subsequent build. Creating the database access class At this point, we have our application created, the MongoDB database embedded, all the information for the baseball stadiums imported, and the dependency for our database driver added to our application. The next step is to do some actual coding by creating a Java class that will act as the interface for connecting to and communicating with the MongoDB database. Create a Java file named DBConnection.java in the mlbparks/src/main/java/org/openshift/mlbparks/mongo directory and add the following source code: package org.openshift.mlbparks.mongo;  import java.net.UnknownHostException; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Named; import com.mongodb.DB; import com.mongodb.Mongo;  @Named @ApplicationScoped public class DBConnection { private DB mongoDB; public DBConnection() {    super(); } @PostConstruct public void afterCreate() {    String mongoHost = System.getenv("OPENSHIFT_MONGODB_DB_HOST");    String mongoPort = System.getenv("OPENSHIFT_MONGODB_DB_PORT");    String mongoUser = System.getenv("OPENSHIFT_MONGODB_DB_USERNAME");    String mongoPassword = System.getenv("OPENSHIFT_MONGODB_DB_PASSWORD");    String mongoDBName = System.getenv("OPENSHIFT_APP_NAME");    int port = Integer.decode(mongoPort);    Mongo mongo = null;  try {     mongo = new Mongo(mongoHost, port);    } catch (UnknownHostException e) {     System.out.println("Couldn't connect to MongoDB: " + e.getMessage() + " :: " + e.getClass());    }    mongoDB = mongo.getDB(mongoDBName);    if (mongoDB.authenticate(mongoUser, mongoPassword.toCharArray()) == false) {     System.out.println("Failed to authenticate DB ");    } } public DB getDB() {    return mongoDB; } } The preceding source code as well as all source code for this article is available on GitHub at https://github.com/gshipley/mlbparks. The preceding code snippet simply creates an application-scoped bean that is available until the application is shut down. The @ApplicationScoped annotation is used when creating application-wide data or constants that should be available to all the users of the application. We chose this scope because we want to maintain a single connection class for the database that is shared among all requests. The next bit of interesting code is the afterCreate method that gets authenticated on the database using the system environment variables. Once you have created the DBConnection.java file and added the preceding source code, add the file to your local repository and commit the changes as follows: $ git add . $ git commit -am "Adding database connection class" Creating the beans.xml file The DBConnection class we just created makes use of Context Dependency Injection (CDI), which is part of the Java EE specification, for dependency injection. According to the official specification for CDI, an application that uses CDI must have a file called beans.xml. The file must be present and located under the WEB-INF directory. Given this requirement, create a file named beans.xml under the mlbparks/src/main/webapp/WEB-INF directory and add the following lines of code: <?xml version="1.0"?> <beans xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd"/> After you have added the beans.xml file, add and commit it to your local Git repository: $ git add . $ git commit -am "Adding beans.xml for CDI" Summary In this article we learned about the evolution of Java EE, created a JBoss EAP application, and created the database access class. Resources for Article: Further resources on this subject: Using OpenShift [Article] Common performance issues [Article] The Business Layer (Java EE 7 First Look) [Article]
Read more
  • 0
  • 0
  • 3454
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-remote-job-agent-oracle-11g-database-oracle-scheduler
Packt
09 Oct 2009
7 min read
Save for later

Remote Job Agent in Oracle 11g Database with Oracle Scheduler

Packt
09 Oct 2009
7 min read
Oracle Scheduler in Oracle 10g is a very powerful tool. However, Oracle 11g has many added advantages that give you more power. In this article by Ronald Rood, we will get our hands on the most important addition to the Scheduler—the remote job agent . This is a whole new kind of process, which allows us to run jobs on machines that do not have a running database. However, they must have Oracle Scheduler Agent installed, as this agent is responsible for executing the remote job. This gives us a lot of extra power and also solves the process owner's problem that exists in classical local external jobs. In classical local external jobs, the process owner is by default nobody and is controlled by $ORACLE_HOME/rdbms/admin/externaljob.ora. This creates problems in installation, where the software is shared between multiple databases because it is not possible to separate the processes. In this article, we will start by installing the software, and then see how we can make good use of it. After this, you will want to get rid of the classical local external jobs as soon as possible because you will want to embrace all the improvements in the remote job agent over the old job type. Security Anything that runs on our database server can cause havoc to our databases. No matter what happens, we want to be sure that our databases cannot be harmed. As we have no control over the contents of scripts that can be called from the database, it seems logical not to have these scripts run by the same operating system user who also owns the Oracle database files and processes. This is why, by default, Oracle chose the user nobody as the default user to run the classical local external jobs. This can be adjusted by editing the contents of $ORACLE_HOME/rdbms/admin/externaljob.ora. On systems where more databases are using the same $ORACLE_HOME directory, this automatically means that all the databases run their external jobs using the same operating system account. This is not very flexible. Luckily for us, Oracle has changed this in the 11g release where remote external jobs are introduced. In this release, Oracle decoupled the job runner process and the database processes. The job runner process, that is the job agent, now runs as a remote process and is contacted using a host:port combination over TCP/IP. The complete name for the agent is remote job agent, but this does not mean the job agent can be installed only remotely. It can be installed on the same machine where the database runs, and where it can easily replace the old-fashioned remote jobs. As the communication is done by TCP/IP, this job agent process can be run using any account on the machine. Oracle has no recommendations for the account, but this could very well be nobody. The operating system user who runs the job agent does need some privileges in the $ORACLE_HOME directory of the remote job agent, namely, an execution privilege on $ORACLE_HOME/bin/* as well as read privileges on $ORACLE_HOME/lib/*. At the end of the day, the user has to be able to use the software. The remote job agent should also have the ability to write its administration (log) in a location that (by default) is in $ORACLE_HOME/data, but it can be configured to a different location by setting the EXECUTION_AGENT_DATA environment variable. In 11g, Oracle also introduced a new object type called CREDENTIAL. We can create credentials using dbms_scheduler.create_credential. This allows us to administrate which operating system user is going to run our jobs in the database. This also allows us to have control over who can use this credential. To see which credentials are defined, we can use the *_SCHEDULER_CREDENTIAL views. We can grant access to a credential by granting execute privilege on the credential. This adds lots more control than we ever had in Oracle 10gR2. Currently, the Scheduler Agent can only use a username-password combination to authenticate against the operating system. The jobs scheduled on the remote job agent will run using the account specified in the credential that we use in the job definition. Check the Creating job section to see how this works. This does introduce a small problem in maintenance. On many systems, customers are forced to use security policies such as password aging. When combining with credentials, this might cause a credential to become invalid. Any change in the password of a job runtime account needs to be reflected in the credential definition that uses the account. As we get much more control over who executes a job, it is strongly recommend to use the new remote job agent in favor of the classical local external jobs, even locally. The classical external job type will soon become history. A quick glimpse with a wireshark, a network sniffer, does not reveal the credentials in the clear text, so it looks like it's secure by default. However, the job results do pass in clear text. The agent and the database communicate using SSL and because of this, a certificate is installed in the ${EXECUTION_AGENT_DATA}/agent.key.  You can check this certificate using Firefox. Just point your browser to the host:port where the Scheduler Agent is running and use Firefox to examine the certificate. There is a bug in 11.1.0.6 that generates a certificate with an expiration date of 90 days past the agent's registration date. In such a case, you will start receiving certificate validation errors when trying to launch a job. Stopping the agent can solve this. Just remove the agent.key and re-register the agent with the database. The registration will be explained in this article shortly. Installation on Windows We need to get the software before the installation can take place. The Scheduler Agent can be found on the Transparent Gateways disk, which can be downloaded from Oracle technet at http://www.oracle.com/technology/software/products/database/index.html. There's no direct link to this software, so find a platform of your choice and click on See All to get the complete list of database software products for that platform. Then download the Oracle Database Gateways CD. Unzip the installation CD, and then navigate to the setup program found in the top level folder and start it. The following screenshot shows the download directory where you run the setup file: After running the setup, the following Welcome screen will appear. The installation process is simple. Click on the Next button to continue to the product selection screen. Select Oracle Scheduler Agent 11.1.0.6.0 and click on the Next button to continue. Enter Name and Path for ORACLE_HOME (we can keep the default values). Now click on Next to reach the screen where we can choose a port on which the database can contact the agent. I chose 15021. On Unix systems, pick a port above 1023 because the lower ports require root privileges to open. The port should be unused and easily memorizable, and should not be used by the database's listener process. If possible, keep all the remote job agents registered to the same database and the same port. Also, don't forget to open the firewall for that port. Hitting the Next button brings us to the following Summary screen: We click on the Install button to complete the installation. If everything goes as expected, the End of Installation screen pops up as follows: Click on the Exit button and confirm the exit. We can find Oracle Execution Agent in the services control panel. Make sure it is running when you want to use the agent to run jobs.
Read more
  • 0
  • 0
  • 3452

article-image-adding-feedback-moodle-quiz-questions
Packt
08 Apr 2013
4 min read
Save for later

Adding Feedback to the Moodle Quiz Questions

Packt
08 Apr 2013
4 min read
(For more resources related to this topic, see here.) Getting ready Any learner taking a quiz may want to know how well he/she has answered the questions posed. Often, working with Moodle, the instructor is at a distance from the learner. Providing feedback is a great way of enhancing communication between learner and instructor. Learner feedback can be provided at multiple levels using Moodle Quiz. You can create feedback at various levels in both the questions and the overall quiz. Here we will examine feedback at the question level. General feedback When we add General Feedback to a question, every student sees the feedback, regardless of their answer to the question. This is good opportunity to provide clarification for the learner who had guessed a correct answer, as well as for the learner whose response was incorrect. Individual response feedback We can create feedback tailored to each possible response in a multiple choice question. This feedback can be more focused in nature. Often, a carefully crafted distracter in a multiple choice can reveal misconceptions and the feedback can provide the correction required as soon as the learner completes the quiz. Feedback given when the question is fresh in the learner's mind, is very effective. How to do it... Let's create some learner feedback for some of the questions that we have created in the question bank: First of all, let's add general feedback to a question. Returning to our True-False question on Texture, we can see that general feedback is effective when there are only two choices. Remember that this type of feedback will appear for all learners, regardless of the answer they submitted. The intention of this feedback is to reflect the correct solution and also give more background information to enhance the teaching opportunity. Let's take a look at how to create a specific feedback for each possible response that a learner may submit. This is done by adding individual response feedback. Returning to our multiple choice question on application of the element line, a specific feedback response tailored to each possible choice will provide helpful clarification for the student. This type of feedback is entered after each possible choice. Here is an example of a feedback to reinforce a correct response and a feedback for an incorrect response: In this case, the feedback the learner receives is tailored to the response they have submitted. This provides much more specific feedback to the learner's choice of responses. For the embedded question (Cloze), feedback is easy to add in Moodle 2.0. In the following screenshot, we can see the question that we created with feedback added: And this is what the feedback looks like to the student: How it works... We have now improved questions in our exam bank by providing feedback for the learner. We have created both general feedback that all learners will see and specific feedback for each response the learner may choose. As we think about the learning experience for the learner, we can see that immediate feedback with our questions is an effective way to reinforce learning. This is another feature that makes Moodle Quiz such a powerful tool. There's more... As we think about the type of feedback we want for the learner, we can combine feedback for individual responses with general feedback. Also there are options for feedback for any correct response, for any partially correct response, or for any incorrect response. Feedback serves to engage the learners and personalize the experience. We created question categories, organized our questions into categories, and learned how to add learner feedback at various levels inside the questions. We are now ready to configure a quiz. Summary In the article we have seen how we can add feedback to the questions of the Moodle Quiz. Resources for Article : Further resources on this subject: Integrating Moodle 2.0 with Mahara and GoogleDocs for Business [Article] What's New in Moodle 2.0 [Article] Moodle 2.0 FAQs [Article]
Read more
  • 0
  • 0
  • 3448

article-image-using-spritefonts-board-based-game-xna-40
Packt
30 Sep 2010
10 min read
Save for later

Using SpriteFonts in a Board-based Game with XNA 4.0

Packt
30 Sep 2010
10 min read
  XNA 4.0 Game Development by Example: Beginner's Guide Create your own exciting games with Microsoft XNA 4.0 Dive headfirst into game creation with XNA Four different styles of games comprising a puzzler, a space shooter, a multi-axis shoot 'em up, and a jump-and-run platformer Games that gradually increase in complexity to cover a wide variety of game development techniques Focuses entirely on developing games with the free version of XNA Packed with many suggestions for expanding your finished game that will make you think critically, technically, and creatively Fresh writing filled with many fun examples that introduce you to game programming concepts and implementation with XNA 4.0 A practical beginner's guide with a fast-paced but friendly and engaging approach towards game development Read more about this book (For more resources on XNA 4.0, see here.) SpriteFonts Unlike a Windows Forms application, XNA cannot use the TrueType fonts that are installed on your computer. In order to use a font, it must first be converted into a SpriteFont, a bitmap based representation of the font in a particular size that can be drawn with the SpriteBatch.DrawString() command. Technically, any Windows font can be turned into a SpriteFont, but licensing restrictions on most fonts will prevent you from using them in your XNA games. The redistributable font package is provided by Microsoft to address this problem and give XNA developers a range of usable fonts that can be included in XNA games. Following are samples of each of the fonts included in the font package: Time for action – add SpriteFonts to Game1 Right click on the Fonts folder in the Content project in Solution Explorer and select Add | New Item. From the Add New Item dialog, select Sprite Font. Name the font Pericles36.spritefont. After adding the font, the spritefont file will open in the editor window. In the spritefont file, change <Fontname>Kootenay</Fontname> to <Fontname>Pericles</Fontname>. Change <Size>14</Size> to <Size>36</Size>. Add the following declaration to the Game1 class: SpriteFont pericles36Font; Update the LoadContent() method of the Game1 class to load spritefont by adding: pericles36Font = Content.Load<SpriteFont>(@"FontsPericles36"); What just happened? Adding a SpriteFont to your game is very similar to adding a texture image. Since both are managed by the Content Pipeline, working with them is identical from a code standpoint. In fact, SpriteFonts are really just specialized sprite sheets, similar to what we used for our game pieces, and are drawn via the same SpriteBatch class we use to draw our sprites. The .spritefont file that gets added to your project is actually an XML document containing information that the Content Pipeline uses to create the .XNB file that holds the bitmap information for the font when you compile your code. The .spritefont file is copied from a template, so no matter what you call it, the XML will always default to 14 point Kootenay. In steps 4 and 5, we will edit the XML to generate 36 point Pericles instead. Just as with a Texture2D, we declare a variable (this time a SpriteFont) to hold the Pericles 36 point font. The Load() method of the Content object is used to load the font. SpriteFonts and extended charactersWhen a SpriteFont is built by the Content Processor, it actually generates bitmap images for each of the characters in the font. The range of characters generated is controlled by the <CharacterRegions> section in the SpriteFont's XML description. If you attempt to output a character not covered by this range, your game will crash. You can avoid this by removing the HTML comment characters (<!--and -->) from around the <DefaultCharacter> definition in the XML file. Whenever an unknown character is output, the character defined in <DefaultCharacter> will be used in its place. Score display Displaying the player's score with our new SpriteFont is simply a matter of calling the SpriteBatch.DrawString() method. Time for action – drawing the score Add a new Vector2 to the declarations area of Game1 to store the screen location where the score will be drawn: Vector2 scorePosition = new Vector2(605, 215); In the Draw() method, remove "this.Window.Title = playerScore.ToString();" and replace the line with: ToString();" and replace the line with:spriteBatch.DrawString(pericles36Font, playerScore.ToString(), scorePosition, Color.Black); What just happened? Using named vectors to store things like text positions, allows you to easily move them around later if you decide to modify the layout of your game screen. It also makes code more readable, as we have the name scorePosition instead of a hard-coded vector value in the spriteBatch.DrawString() call. Since our window size is set to 800 by 600 pixels, the location we have defined above will place the score into the pre-defined score box on our background image texture. The DrawString() method accepts a font to draw with (pericles36Font), a string to output (playerScore.ToString()), a Vector2 specifying the upper left corner of the location to begin drawing (scorePosition), and a color for the text to be drawn in (Color.Black). ScoreZooms Simply drawing the player's score is not very exciting, so let's add another use for our SpriteFont. In some puzzle games, when the player scores, the number of points earned is displayed in the center of the screen, rapidly growing larger and expanding until it flies off of the screen toward the player. We will implement this functionality with a class called ScoreZoom that will handle scaling the font. Time for action – creating the ScoreZoom class Add a new class file called ScoreZoom.cs to the Game1 class. Add the following using directive to the top of the file: using Microsoft.Xna.Framework.Graphics; Add the following declarati ons to the ScoreZoom class: public string Text;public Color DrawColor;private int displayCounter;private int maxDisplayCount = 30;private float scale = 0.4f;private float lastScaleAmount = 0.0f;private float scaleAmount = 0.4f; Add the Scale read-only property to the ScoreZoom class: public float Scale{ get { return scaleAmount * displayCounter; }} Add a Boolean property to indicate when the ScoreZoom has finished displaying: public bool IsCompleted{ get { return (displayCounter > maxDisplayCount); }} Create a constructor for the ScoreZoom class: public ScoreZoom(string displayText, Color fontColor){ Text = displayText; DrawColor = fontColor; displayCounter = 0;} Add an Update() method to the ScoreZoom class: public void Update(){ scale += lastScaleAmount + scaleAmount; lastScaleAmount += scaleAmount; displayCounter++;} What just happened? The ScoreZoom class holds some basic information about a piece of text and how it will be displayed to the screen. The number of frames the text will be drawn for are determined by displayCounter and maxDisplayCount. To manage the scale, three variables are used: scale contains the actual scale size that will be used when drawing the text, lastScaleAmount holds the amount the scale was increased by during the previous frame, and scaleAmount determines the growth in the scale factor during each frame. You can see how this is used in the Update() method. The current scale is increased by both the lastScaleAmount and scaleAmount. lastScaleAmount is then increased by the scale amount. This results in the scale growing in an exponential fashion instead of increasing linearly by a scaleAmount for each frame. This will give the text a zooming effect as it starts growing slowly and then speeds up rapidly to fill the screen. Time for action – updating and displaying ScoreZooms Add a Queue object to the Game1 class to hold active ScoreZooms: Queue<ScoreZoom> ScoreZooms = new Queue<ScoreZoom>(); Add a new helper method to the Game1 class to update the ScoreZooms queue: private void UpdateScoreZooms(){ int dequeueCounter = 0; foreach (ScoreZoom zoom in ScoreZooms) { zoom.Update(); if (zoom.IsCompleted) dequeueCounter++; } for (int d = 0; d < dequeueCounter; d++) ScoreZooms.Dequeue();} In the Update() method, inside the case section for GameState.Playing, add the call to update any active ScoreZooms. This can be placed right before the case's break; statement: UpdateScoreZooms(); Add the following to the CheckScoringChain() method to create a ScoreZoom when the player scores. Add this right after the playerScore is increased: ScoreZooms.Enqueue(new ScoreZoom("+" + DetermineScore(WaterChain.Count).ToString(), new Color(1.0f, 0.0f, 0.0f, 0.4f))); Modify the Draw() method of the Game1 class by adding the following right before the SpriteBatch.DrawString() call which draws the player's score: foreach (ScoreZoom zoom in ScoreZooms){ spriteBatch.DrawString(pericles36Font, zoom.Text, new Vector2(this.Window.ClientBounds.Width / 2, this.Window.ClientBounds.Height / 2), zoom.DrawColor, 0.0f, new Vector2(pericles36Font.MeasureString(zoom.Text).X / 2, pericles36Font.MeasureString(zoom.Text).Y / 2), zoom.Scale, SpriteEffects.None, 0.0f);} What just happened? Since all ScoreZoom objects "live" for the same amount of time, we can always be certain that the first one we create will finish before any created during a later loop. This allows us to use a simple Queue to hold ScoreZooms since a Queue works in a first-in-first-out manner. When UpdateScoreZooms() is executed, the dequeueCounter holds the number of ScoreZoom objects that have finished updating during this cycle. It starts at zero, and while the foreach loop runs, any ScoreZoom that has an IsCompleted property of true increments the counter. When the foreach has completed, ScoreZooms.Dequeue() is run a number of times equal to dequeueCounter. Adding new ScoreZoom objects is accomplished in step 4, with the Enqueue() method. The method is passed a new ScoreZoom object, which is constructed with a plus sign (+) and the score being added, followed by a red color with the alpha value set to 0.4f, making it a little more than halfway transparent. Just as the SpriteBatch.Draw() method has multiple overloads, so does the SpriteBatch.DrawString() method, and in fact, they follow much the same pattern. This form of the DrawString() method accepts the SpriteFont (pericles36Font), the text to display, a location vector, and a draw color just like the previous call. For the draw location in this case, we use this.Window.ClientBounds to retrieve the width and height of the game window. By dividing each by two, we get the coordinates of the center of the screen. The remaining parameters are the same as those of the extended Draw() call we used to draw rotated pieces. After the color value is rotation, which we have set to 0.0f, followed by the origin point for that rotation. We have used the MeasureString() method of the SpriteFont class to determine both the height and width of the text that will be displayed and divided the value by two to determine the center point of the text. Why do this when there is no rotation happening? Despite what the order of the parameters might indicate, this origin also impacts the next parameter: the scale. When the scale is applied, it sizes the text around the origin point. If we were to leave the origin at the default (0, 0), the upper left corner of the text would remain in the center of the screen and it would grow towards the bottom right corner. By setting the origin to the center of the text, the scale is applied evenly in all directions: Just as with the extended Draw() method earlier, we will use SpriteEffects.None for the spriteEffects parameter and 0.0f for the layer depth, indicating that the text should be drawn on top of whatever has been drawn already. Adding the GameOver game state Now that we can draw text, we can add a new game state in preparation for actually letting the game end when the facility floods.
Read more
  • 0
  • 0
  • 3446

article-image-unity-3-0-enter-third-dimension
Packt
28 Dec 2011
10 min read
Save for later

Unity 3-0 Enter the Third Dimension

Packt
28 Dec 2011
10 min read
(For more resources on Unity 3D, see here.) Getting to grips with 3D Let's take a look at the crucial elements of 3D worlds, and how Unity lets you develop games in three dimensions. Coordinates If you have worked with any 3D application before, you'll likely be familiar with the concept of the Z-axis. The Z-axis, in addition to the existing X for horizontal and Y for vertical, represents depth. In 3D applications, you'll see information on objects laid out in X, Y, Z format—this is known as the Cartesian coordinate method. Dimensions, rotational values, and positions in the 3D world can all be described in this way. As in other documentation of 3D, you'll see such information written with parenthesis, shown as follows: (3, 5, 3) This is mostly for neatness, and also due to the fact that in programming, these values must be written in this way. Regardless of their presentation, you can assume that any sets of three values separated by commas will be in X, Y, Z order. In the following image, a cube is shown at location (3,5,3) in the 3D world, meaning it is 3 units from 0 in the X-axis, 5 up in the Y-axis, and 3 forward in the Z-axis: Local space versus world space A crucial concept to begin looking at is the difference between local space and world space. In any 3D package, the world you will work in is technically infinite, and it can be difficult to keep track of the location of objects within it. In every 3D world, there is a point of origin, often referred to as the 'origin'> or 'world zero', as it is represented by the position (0,0,0). All world positions of objects in 3D are relative to world zero. However, to make things simpler, we also use local space (also known as object space) to define object positions in relation to one another. These relationships are known as parent-child relationships. In Unity, parent-child relationships can be established easily by dragging one object onto another in the Hierarchy. This causes the dragged object to become a child, and its coordinates from then on are read in terms relative to the parent object. For example, if the child object is exactly at the same world position as the parent object, its position is said to be (0,0,0), even if the parent position is not at world zero. Local space assumes that every object has its own zero point, which is the point from which its axes emerge. This is usually the center of the object, and by creating relationships between objects, we can compare their positions in relation to one another. Such relationships, known as parent-child relationships, mean that we can calculate distances from other objects using local space, with the parent object's position becoming the new zero point for any of its child objects. This is especially important to bear in mind when working on art assets in 3D modelling tools, as you should always ensure that your models are created at 0,0,0 in the package that you are using. This is to ensure that when imported into Unity, their axes are read correctly. We can illustrate this in 2D, as the same conventions will apply to 3D. In the following example: The first diagram (i) shows two objects in world space. A large cube exists at coordinates(3,3), and a smaller one at coordinates (6,7). In the second diagram (ii), the smaller cube has been made a child object of the larger cube. As such the smaller cube's coordinates are said to be (3,4), because its zero point is the world position of the parent. Vectors You'll also see 3D vectors described in Cartesian coordinates. Like their 2D counterparts, 3D vectors are simply lines drawn in the 3D world that have a direction and a length. Vectors can be moved in world space, but remain unchanged themselves. Vectors are useful in a game engine context, as they allow us to calculate distances, relative angles between objects, and the direction of objects. Cameras Cameras are essential in the 3D world, as they act as the viewport for the screen. Cameras can be placed at any point in the world, animated, or attached to characters or objects as part of a game scenario. Many cameras can exist in a particular scene, but it is assumed that a single main camera will always render what the player sees. This is why Unity gives you a Main Camera object whenever you create a new scene. Projection mode—3D versus 2D The Projection mode of a camera states whether it renders in 3D (Perspective) or 2D (Orthographic). Ordinarily, cameras are set to Perspective Projection mode, and as such have a pyramid shaped Field of View (FOV). A Perspective mode camera renders in 3D and is the default Projection mode for a camera in Unity. Cameras can also be set to Orthographic Projection mode in order to render in 2D—these have a rectangular field of view. This can be used on a main camera to create complete 2D games or simply used as a secondary camera used to render Heads Up Display (HUD) elements such as a map or health bar. In game engines, you'll notice that effects such as lighting, motion blurs, and other effects are applied to the camera to help with game simulation of a person's eye view of the world—you can even add a few cinematic effects that the human eye will never experience, such as lens flares when looking at the sun! Most modern 3D games utilize multiple cameras to show parts of the game world that the character camera is not currently looking at—like a 'cutaway' in cinematic terms. Unity does this with ease by allowing many cameras in a single scene, which can be scripted to act as the main camera at any point during runtime. Multiple cameras can also be used in a game to control the rendering of particular 2D and 3D elements separately as part of the optimization process. For example, objects may be grouped in layers, and cameras may be assigned to render objects in particular layers. This gives us more control over individual renders of certain elements in the game. Polygons, edges, vertices, and meshes In constructing 3D shapes, all objects are ultimately made up of interconnected 2D shapes known as polygons. On importing models from a modeling application, Unity converts all polygons to polygon triangles. By combining many linked polygons, 3D modeling applications allow us to build complex shapes, known as meshes. Polygon triangles (also referred to as faces) are in turn made up of three connected edges. The locations at which these edges meet are known as points or vertices. By knowing these locations, game engines are able to make calculations regarding the points of impact, known as collisions, when using complex collision detection with Mesh Colliders, such as in shooting games to detect the exact location at which a bullet has hit another object. In addition to building 3D shapes that are rendered visibly, mesh data can have many other uses. For example, it can be used to specify a shape for collision that is less detailed than a visible object, but roughly the same shape. This can help save performance as the physics engine needn't check a mesh in detail for collisions. This is seen in the following image from the Unity car tutorial, where the vehicle itself is more detailed than its collision mesh: In the second image, you can see that the amount of detail in the mesh used for the collider is far less than the visible mesh itself: In game projects, it is crucial for the developer to understand the importance of the polygon count. The polygon count is the total number of polygons, often in reference to models, but also in reference to props, or an entire game level (or in Unity terms, 'Scene'). The higher the number of polygons, the more work your computer must do to render the objects onscreen. This is why we've seen an increase in the level of detail from early 3D games to those of today. Simply compare the visual detail in a game such as id's Quake(1996) with the details seen in Epic's Gears Of War (2006) in just a decade. As a result of faster technology, game developers are now able to model 3D characters and worlds, for games that contain a much higher polygon count and resultant level of realism, and this trend will inevitably continue in the years to come. This said, as more platforms emerge such as mobile and online, games previously seen on dedicated consoles can now be played in a web browser thanks to Unity. As such, the hardware constraints are as important now as ever, as lower powered devices such as mobile phones and tablets are able to run 3D games. For this reason, when modeling any object to add to your game, you should consider polygonal detail, and where it is most required. Materials, textures, and shaders Materials are a common concept to all 3D applications, as they provide the means to set the visual appearance of a 3D model. From basic colors to reflective image-based surfaces, materials handle everything. Let's start with a simple color and the option of using one or more images—known as textures. In a single material, the material works with the shader, which is a script in charge of the style of rendering. For example, in a reflective shader, the material will render reflections of surrounding objects, but maintain its color or the look of the image applied as its texture. In Unity, the use of materials is easy. Any materials created in your 3D modeling package will be imported and recreated automatically by the engine and created as assets that are reusable. You can also create your own materials from scratch, assigning images as textures and selecting a shader from a large library that comes built-in. You may also write your own shader scripts or copy-paste those written by fellow developers in the Unity community, giving you more freedom for expansion beyond the included set. When creating textures for a game in a graphics package such as Photoshop or GIMP, you must be aware of the resolution. Larger textures will give you the chance to add more detail to your textured models, but be more intensive to render. Game textures imported into Unity will be scaled to a power of 2 resolution. For example: 64px x 64px 128px x 128px 256px x 256px 512px x 512px 1024px x 1024px Creating textures of these sizes with content that matches at the edges will mean that they can be tiled successfully by Unity. You may also use textures scaled to values that are not powers of two, but mostly these are used for GUI elements.  
Read more
  • 0
  • 0
  • 3446
article-image-arcgis-spatial-analyst
Packt
20 Jan 2015
16 min read
Save for later

ArcGIS Spatial Analyst

Packt
20 Jan 2015
16 min read
In this article by Daniela Cristiana Docan, author of ArcGIS for Desktop Cookbook, we will learn that the ArcGIS Spatial Analyst extension offers a lot of great tools for geoprocessing raster data. Most of the Spatial Analyst tools generate a new raster output. Before starting a raster analysis session, it's best practice to set the main analysis environment parameters settings (for example, scratch the workspace, extent, and cell size of the output raster). In this article, you will store all raster datasets in file geodatabase as file geodatabase raster datasets. (For more resources related to this topic, see here.) Analyzing surfaces In this recipe, you will represent 3D surface data in a two-dimensional environment. To represent 3D surface data in the ArcMap 2D environment, you will use hillshades and contours. You can use the hillshade raster as a background for other raster or vector data in ArcMap. Using the surface analysis tools, you can derive new surface data, such as slope and aspect or locations visibility. Getting ready In the surface analysis context: The term slope refers to the steepness of raster cells Aspect defines the orientation or compass direction of a cell Visibility identifies which raster cells are visible from a surface location In this recipe, you will prepare your data for analysis by creating an elevation surface named Elevation from vector data. The two feature classes involved are the PointElevation point feature class and the ContourLine polyline feature class. All other output raster datasets will derive from the Elevation raster. How to do it... Follow these steps to prepare your data for spatial analysis: Start ArcMap and open the existing map document, SurfaceAnalysis.mxd, from <drive>:PacktPublishingDataSpatialAnalyst. Go to Customize | Extensions and check the Spatial Analyst extension. Open ArcToolbox, right-click on the ArcToolbox toolbox, and select Environments. Set the geoprocessing environment as follows: Workspace | Current Workspace: DataSpatialAnalystTOPO5000.gdb and Scratch Workspace: DataSpatialAnalystScratchTOPO5000.gdb. Output Coordinates: Same as Input. Raster Analysis | Cell Size: As Specified below: type 0.5 with unit as m. Mask: SpatialAnalystTOPO5000.gdbTrapezoid5k. Raster Storage | Pyramid: check Build pyramids and Pyramid levels: type 3. Click on OK. In ArcToolbox, expand Spatial Analyst Tools | Interpolation, and double-click on the Topo to Raster tool to open the dialog box. Click on Show Help to see the meaning of every parameter. Set the following parameters: Input feature data: PointElevation Field: Elevation and Type: PointElevation ContourLine Field: Elevation and Type: Contour WatercourseA Type: Lake Output surface raster: ...ScratchTOPO5000.gdbElevation Output extent (optional): ContourLine Drainage enforcement (optional): NO_ENFORCE Accept the default values for all other parameters. Click on OK. The Elevation raster is a continuous thematic raster. The raster cells are arranged in 4,967 rows and 4,656 columns. Open Layer Properties | Source of the raster and explore the following properties: Data Type (File Geodatabase Raster Dataset), Cell Size (0.5 meters) or Spatial Reference (EPSG: 3844). In the Layer Properties window, click on the Symbology tab. Select the Stretched display method for the continuous raster cell values as follows: Show: Stretched and Color Ramp: Surface. Click on OK. Explore the cell values using the following two options: Go to Layer Properties | Display and check Show MapTips Add the Spatial Analyst toolbar, and from Customize | Commands, add the Pixel Inspector tool Let's create a hillshade raster using the Elevation layer: Expand Spatial Analyst Tools | Interpolation and double-click on the Hillshade tool to open the dialog box. Set the following parameters: Input raster: ScratchTOPO5000.gdbElevation Output raster: ScratchTOPO5000.gdbHillshade Azimuth (optional): 315 and Altitude (optional): 45 Accept the default value for Z factor and leave the Model shadows option unchecked. Click on OK. From time to time, please ensure to save the map document as MySurfaceAnalysis.mxd at ...DataSpatialAnalyst. The Hillshade raster is a discrete thematic raster that has an associated attribute table known as Value Attribute Table (VAT). Right-click on the Hillshade raster layer and select Open Attribute Table. The Value field stores the illumination values of the raster cells based on the position of the light source. The 0 value (black) means that 25406 cells are not illuminated by the sun, and 254 value (white) means that 992 cells are entirely illuminated. Close the table. In the Table Of Contents section, drag the Hillshade layer below the Elevation layer, and use the Effects | Transparency tool to add a transparency effect for the Elevation raster layer, as shown in the following screenshot: In the next step, you will derive a raster of slope and aspect from the Elevation layer. Expand Spatial Analyst Tools | Interpolation and double-click on the Slope tool to open the dialog box. Set the following parameters: Input raster: Elevation Output raster: ScratchTOPO5000.gdbSlopePercent Output measurement (optional): PERCENT_RISE Click on OK. Symbolize the layer using the Classified method, as follows: Show: Classified. In the Classification section, click on Classify and select the Manual classification method. You will add seven classes. To add break values, right-click on the empty space of the Insert Break graph. To delete one, select the break value from the graph, and right-click to select Delete Break. Do not erase the last break value, which represents the maximum value. Secondly, in the Break Values section, edit the following six values: 5; 7; 15; 20; 60; 90, and leave unchanged the seventh value (496,6). Select Slope (green to red) for Color Ramp. Click on OK. The green areas represent flatter slopes, while the red areas represent steep slopes, as shown in the following screenshot: Expand Spatial Analyst Tools | Interpolation and double click on the Aspect tool to open the dialog box. Set the following parameters: Input raster: Elevation Output raster: ScratchTOPO5000.gdbAspect Click on OK. Symbolize the Aspect layer. For Classify, click on the Manual classification method. You will add five classes. To add or delete break values, right-click on the empty space of the graph, and select Insert / Delete Break. Secondly, edit the following four values: 0; 90; 180; 270, leaving unchanged the fifth value in the Break Values section. Click on OK. In the Symbology window, edit the labels of the five classes as shown in the following picture. Click on OK. In the Table Of Contents section, select the <VALUE> label, and type Slope Direction. The following screenshot is the result of this action: In the next step, you will create a raster of visibility between two geodetic points in order to plan some topographic measurements using an electronic theodolite. You will use the TriangulationPoint and Elevation layers: In the Table Of Contents section, turn on the TriangulationPoint layer, and open its attribute table to examine the fields. There are two geodetic points with the following supplementary fields: OffsetA and OffsetB. OffsetA is the proposed height of the instrument mounted on its tripod above stations 8 and 72. OffsetB is the proposed height of the reflector (or target) above the same points. Close the table. Expand Spatial Analyst Tools | Interpolation and double-click on the Visibility tool to open the dialog box. Click on Show Help to see the meaning of every parameter. Set the following parameters: Input raster: Elevation Input point or polyline observer features: TOPO5000.gdbGeodeticPointsTriangulationPoint Output raster: ScratchTOPO5000.gdbVisibility Analysis type (optional): OBSERVERS Observer parameters | Surface offset (optional): OffsetB Observer offset (optional): OffsetA Outer radius (optional): For this, type 1600 Notice that OffsetA and OffsetB were automatically assigned. The Outer radius parameter limits the search distance, and it is the rounded distance between the two geodetic points. All other cells beyond the 1,600-meter radius will be excluded from the visibility analysis. Click on OK. Open the attribute table of the Visibility layer to inspect the fields and values. The Value field stores the value of cells. Value 0 means that cells are not visible from the two points. Value 1 means that 6,608,948 cells are visible only from point 8 (first observer OBS1). Value 2 means that 1,813,578 cells are visible only from point 72 (second observer OBS2). Value 3 means that 4,351,861 cells are visible from both points. In conclusion, there is visibility between the two points if the height of the instrument and reflector is 1.5 meters. Close the table. Symbolize the Visibility layer, as follows: Show: Unique Values and Value Field: Value. Click on Add All Values and choose Color Scheme: Yellow-Green Bright. Select <Heading> and change the Label value to Height 1.5 meters. Double-click on the symbol for Value as 0, and select No Color. Click on OK. The Visibility layer is symbolized as shown in the following screenshot: Turn off all layers except the Visibility, TriangulationPoint, and Hillshade layers. Save your map as MySurfaceAnalysis.mxd and close ArcMap. You can find the final results at <drive>:PacktPublishingDataSpatialAnalystSurfaceAnalysis. How it works... You have started the exercise by setting the geoprocessing environment. You will override those settings in the next recipes. At the application level, you chose to build pyramids. By creating pyramids, your raster will be displayed faster when you zoom out. The pyramid levels contain the copy of the original raster at a low resolution. The original raster will have a cell size of 0.5 meters. The pixel size will double at each level of the pyramid, so the first level will have a cell size of 1 meter; the second level will have a cell size of 2 meters; and the third level will have a cell size of 4 meters. Even if the values of cells refer to heights measured above the local mean sea level (zero-level surface), you should consider the planimetric accuracy of the dataset. Please remember that TOPO5000.gdb refers to a product at the scale 1:5,000. This is the reason why you have chosen 0.5 meters for the raster cell size. At step 4, you used the PointElevation layer as supplementary data when you created the Elevation raster. If one of your ArcToolbox tools fails to execute or you have obtained an empty raster output, you have some options here: Open the Results dialog from the Geoprocessing menu to explore the error report. This will help you to identify the parameter errors. Right-click on the previous execution of the tool and choose Open (step 1). Change the parameters and click on OK to run the tool. Choose Re Run if you want to run the tool with the parameters unchanged (step 2) as shown in the following screenshot: Run the ArcToolbox tool from the ArcCatalog application. Before running the tool, check the geoprocessing environment in ArcCatalog by navigating to Geoprocessing | Environments. There's more... What if you have a model with all previous steps? Open ArcCatalog, and go to ...DataSpatialAnalystModelBuilder. In the ModelBuilder folder, you have a toolbox named MyToolbox, which contains the Surface Analysis model. Right-click on the model and select Properties. Take your time to study the information from the General, Parameters, and Environments tabs. The output (derived data) will be saved in Scratch Workspace: ModelBuilder ScratchTopo5000.gdb. Click on OK to close the Surface Analysis Properties window. Running the entire model will take you around 25 minutes. You have two options: Tool dialog option: Right-click on the Surface Analysis model and select Open. Notice the model parameters that you can modify and read the Help information. Click on OK to run the model. Edit mode: Right-click on the Surface Analysis model and select Edit. The colored model elements are in the second state—they are ready to run the Surface Analysis model by using one of those two options: To run the entire model at the same time, select Run Entire Model from the Model menu. To run the tools (yellow rounded rectangle) one by one, select the Topo to Raster tool with the Select tool, and click on the Run tool from the Standard toolbar. Please remember that a shadow behind a tool means that the model element has already been run. You used the Visibility tool to check the visibility between two points with 1.5 meters for the Observer offset and Surface offset parameters. Try yourself to see what happens if the offset value is less than 1.5 meters. To again run the Visibility tool in the Edit mode, right-click on the tool, and select Open. For Surface offset and Observer offset, type 0.5 meters and click on OK to run the tool. Repeat these steps for a 1 meter offset. Interpolating data Spatial interpolation is the process of estimating an unknown value between two known values taking into account Tobler's First Law: "Everything is related to everything else, but near things are more related than distant things." This recipe does not undertake to teach you the advanced concept of interpolation because it is too complex for this book. Instead, this recipe will guide you to create a terrain surface using the following: A feature class with sample elevation points Two interpolation methods: Inverse Distance Weighted (IDW) and Spline For further research, please refer to: Geographic Information Analysis, David O'Sullivan and David Unwin, John Wiley & Sons, Inc., 2003, specifically the 8.3 Spatial interpolation recipe of Chapter 8, Describing and Analyzing Fields, pp.220-234. Getting ready In this recipe, you will create a terrain surface stored as a raster using the PointElevation sample points. Your sample data has the following characteristics: The average distance between points is 150 meters The density of sample points is not the same on the entire area of interest There are not enough points to define the cliffs and the depressions There are not extreme differences in elevation values How to do it... Follow these steps to create a terrain surface using the IDW tool: Start ArcMap and open an existing map document Interpolation.mxd from <drive>:PacktPublishingDataSpatialAnalyst. Set the geoprocessing environment, as follows: Workspace | Current Workspace: DataSpatialAnalystTOPO5000.gdb and Scratch Workspace: DataSpatialAnalystScratchTOPO5000.gdb Output Coordinates: Same as the PointElevation layer Raster Analysis | Cell Size: As Specified Below: 1 Mask: DataSpatialAnalystTOPO5000.gdbTrapezoid5k In the next two steps, you will use the IDW tool. Running IDW with barrier polyline features will take you around 15 minutes: In ArcToolbox, go to Spatial Analyst Tools | Interpolation, and double-click on the IDW tool. Click on Show Help to see the meaning of every parameter. Set the following parameters: Input point features: PointElevation Z value field: Elevation Output raster: ScratchTOPO5000.gdbIDW_1 Power (optional): 0.5 Search radius (optional): Variable Search Radius Settings | Number of points: 6 Maximum distance: 500 Input barrier polyline features (optional): TOPO5000.gdbHydrographyWatercourseL Accept the default value of Output cell size (optional). Click on OK. Repeat step 3 by setting the following parameters: Input point features: PointElevation Z value field: Elevation Output raster: ScratchTOPO5000.gdbIDW_2 Power (optional): 2 The rest of the parameters are the same as in step 3. Click on OK. Symbolize the IDW_1 and IDW_2 layers as follows: Show: Classified; Classification: Equal Interval: 10 classes; Color Scheme: Surface. Click on OK. You should obtain the following results: In the following steps, you will use the Spline tool to generate the terrain surface: In ArcToolbox, go to Spatial Analyst Tools | Interpolation, and double-click on the Spline tool. Set the following parameters: Input point features: PointElevation Z value field: Elevation Output raster: ScratchTOPO5000.gdbSpline_Regular Spline type (optional): REGULARIZED Weight (optional): 0.1 and Number of points (optional): 6 Accept the default value of Output cell size (optional). Click on OK. Run again the Spline tool with the following parameters: Input point features: PointElevation Z value field: Elevation Output raster: ScratchTOPO5000.gdbSpline_Tension Spline type (optional): TENSION Weight (optional): 0.1 and Number of points (optional): 6 Accept the default value of Output cell size (optional). Click on OK. Symbolize the Spline_Regular and Spline_Tension raster layers using the Equal Interval method classification with 10 classes and the Surface color ramp: In the next steps, you will use the Spline with Barriers tool to generate a terrain surface using an increased number of sample points. You will transform the ContourLine layer in a point feature class. You will combine those new points with features from the PointElevation layer: In ArcToolbox, go to Data Management Tools | Features, and double-click on the Feature vertices to Points tool. Set the following parameters: Input features: ContourLine Output Feature Class: TOPO5000.gdbRelief ContourLine_FeatureVertices Point type (optional): ALL Click on OK. Inspect the attribute table of the newly created layer. In the Catalog window, go to ...TOPO5000.gdbRelief and create a copy of the PointElevation feature class. Rename the new feature class as ContourAndPoint. Right-click on ContourAndPoint and select Load | Load Data. Set the following parameters from the second and fourth panels: Input data: ContourLine_FeatureVertices Target Field: Elevation Matching Source Field: Elevation Accept the default values for the rest of the parameters and click on Finish. In ArcToolbox, go to Spatial Analyst Tools | Interpolation, and double-click on the Spline with Barriers tool. Set the following parameters: Input point features: ContourAndPoint Z value field: Elevation Input barrier features (optional): TOPO5000.gdbHydrographyWatercourseA Output raster: ScratchTOPO5000.gdbSpline_WaterA Smoothing Factor (optional): 0 Accept the default value of Output cell size (optional). Click on OK. You should obtain a similar terrain surface to what's shown here: Explore the results by comparing the similarities or differences of the terrain surface between interpolated raster layers and the ContourLine vector layer. The IDW method works well with a proper density of sample points. Try to create a new surface using the IDW tool and the ContourAndPoint layer as sample points. Save your map as MyInterpolation.mxd and close ArcMap. You can find the final results at <drive>:PacktPublishingDataSpatialAnalyst Interpolation. How it works... The IDW method generated an average surface that will not cross through the known point elevation values and will not estimate the values below the minimum or above the maximum given point values. The IDW tool allows you to define polyline barriers or limits in searching sample points for interpolation. Even if the WatercourseL polyline feature classes do not have elevation values, river features can be used to interrupt the continuity of interpolated surfaces. To obtain fewer averaged estimated values (reduce the IDW smoother effect) you have to: Reduce the sample size to 6 points Choose a variable search radius Increase the power to 2 The Power option defines the influence of sample point values. This value increases with the distance. There is a disadvantage because around a few sample points, there are small areas raised above the surrounding surface or small hollows below the surrounding surface. The Spline method has generated a surface that crosses through all the known point elevation values and estimates the values below the minimum or above the maximum sample point values. Because the density of points is quite low, we reduced the sample size to 6 points and defined a variable search radius of 500 meters in order to reduce the smoothening effect. The Regularized option estimates the hills or depressions that are not cached by the sample point values. The Tension option will force the interpolated values to stay closer to the sample point values. Starting from step 12, we increased the number of sample points in order to better estimate the surface. At step 14, notice that the Spline with Barriers tool allows you to use the polygon feature class as breaks or barriers in searching sample points for interpolation. Summary In this article, we learned about the ArcGIS Spatial Analyst extension and its tools. Resources for Article:   Further resources on this subject: Posting Reviews, Ratings, and Photos [article] Enterprise Geodatabase [article] Adding Graphics to the Map [article]
Read more
  • 0
  • 0
  • 3445

article-image-basic-security-approaches
Packt
19 Sep 2013
10 min read
Save for later

Basic Security Approaches

Packt
19 Sep 2013
10 min read
(For more resources related to this topic, see here.) Security, privacy, and safeguards for intellectual property are at the front of the minds of those of us building Titanium Enterprise apps. Titanium allows you to combine the underlying platform tools and third-party JavaScript libraries to help meet your security requirements. This article provides a series of approaches on how to leverage JavaScript, Titanium modules, and the underlying platform to enable you to create a layered security approach to assist you in meeting your organization's overall secure development goals. Each recipe is designed to provide building blocks to help you implement your industry's existing security and privacy standards. Implementing iOS data protection in Titanium Starting with iOS 4, Apple introduced the ability for apps to use the data protection feature to add an additional level of security for data stored on disk. Data protection uses the built-in hardware encryption to encrypt files stored on the device. This feature is available when the user's device is locked and protected with a passcode lock. During this time, all files are protected and inaccessible until the user explicitly unlocks the device. When the device is locked, no app can access protected files. This even applies to the app that created the file. Getting ready This recipe uses the securely native module for enhanced security functionality. This module and other code assets can be downloaded from the source provided by the book. Installing these in your project is straightforward. Simply copy the modules folder into your project as shown in the following screenshot: After copying the mentioned folder, you will need to click on your tiapp.xml file in Titanium Studio and add a reference to the bencoding.securely module as shown in the following screenshot: Enabling data protection This recipe requires your iOS device to have data protection enabled. You will need a device as the simulator does not support data protection. The following steps cover how to enable this feature on your device: Go to Settings | General | Passcode . Follow the prompts to set up a passcode. After adding a passcode, scroll to the bottom of the screen and verify that the text Data protection is enabled is visible as shown in the following screenshot: iOS device browser A third-party iOS device browser is needed to verify that data protection for the example recipe app has successfully been enabled. This recipe discusses how to verify data protection using the popular iExplorer app. An evaluation version of the iExplorer app can be used to follow along with this recipe. For more information and to download iExplorer, please visit http://www.macroplant.com/iexplorer. How to do it... To enable iOS data protection, the DataProtectionClass and com.apple.developer.default-data-protection keys need to be added to your tiapp.xml as demonstrated in the following code snippet: First, add the ios configuration node if your project does not already contain this element. <ios> <plist> <dict> Then at the top of the dict node, add the following highlighted keys. <key>DataProtectionClass</key> <string>NSFileProtectionComplete</string> <key>com.apple.developer. default-data-protection</key> <string>NSFileProtectionComplete</string> </dict> </plist> </ios>   After saving the updates to your tiapp.xml, you must clean your Titanium project in order to have the updates take effect. This can be done in Titanium Studio by selecting Project | Clean . Creating the namespace and imports Once you have added the securely module and added the tiapp.xml updates to your project, you need to create your application namespace in the app.js file and use require to import the module into your code as the following code snippet demonstrates: //Create our application namespace var my = { secure : require('bencoding.securely') }; Creating the recipe UI The following steps outline how to create the UI used in this recipe: First, a Ti.UI.Window is created to attach all UI elements. var win = Ti.UI.createWindow({ backgroundColor: '#fff', title: 'Data Protection Example', barColor:'#000',layout:'vertical' }); Next, a Ti.UI.Button is added to the Ti.UI.Window. This will be used to trigger our example. var button1 = Ti.UI.createButton({ title:'Create Test File', top:25, height:45, left:5, right:5 }); win.add(button1); Creating a file to verify data protection To verify if data protection is enabled in the app, the recipe creates a time-stamped file in the Ti.Filesystem.applicationDataDirectory directory. Using an iOS device browser, we can verify if the test file is protected when the device is locked. The following steps describe how the recipe creates this test file: The click event for button1 creates a time-stamped file that allows us to verify if data protection has been correctly enabled for the app. button1.addEventListener('click',function(e){ Next the isProtectedDataAvailable method is called on securely. This provides a Boolean result indicating that data protection allows the app to read from or write to the filesystem. if(!my.secure.isProtectedDataAvailable()){ alert('Protected data is not yet available.'); return; } To ensure there is a unique identifier in the file, a token is created using the current date and time. This token is then added to the following message template: var timeToken = String.formatDate(new Date(),"medium") + String.formatTime(new Date()); var msg = "When device is locked you will not be able"; msg += " to read this file. Your time token is "; msg += timeToken; The message created in step 3 is then written to the test.txt file located in the Ti.Filesystem.applicationDataDirectory directory. If the file already exists, it is removed so that the latest message will be available for testing. var testfile = Ti.Filesystem.getFile( Ti.Filesystem.applicationDataDirectory, 'test.txt'); if(testfile.exists()){ testfile.deleteFile(); } testfile.write(msg); testfile = null; Once the test.txt file is written to the device, a message is displayed to the user notifying them to lock their device and use an iOS device browser to confirm data protection is enabled. var alertMsg = "Please lock your device."; alertMsg+= "Then open an iOS Device Browser."; alertMsg+= "The time token you are looking for is "; alertMsg+= timeToken; alert(alertMsg); How it works... After the DataProtectionClass and com.apple.developer.default-data-protection keys have been added to your tiapp.xml, the iOS device handles protecting your files when the device is locked. The following steps discuss how to test that this recipe has correctly implemented data protection: The first step in the validation process is to build and deploy the recipe app to your iOS device. Once the app has been loaded onto your device, open the app and press the Create Test File button. Once you have received an alert message indicating the test file has been created, press the home button and lock your device. Plug your device into a computer with iExplorer installed. Open iExplorer and navigate so that you can view the apps on your device. Select the DataProtection app as marked with the red box in the following screenshot. Then right-click on the test.txt file located in the Documents folder and select Quick Look as marked with the green box in the following screenshot: After Quick Look is selected, iExplorer will try to open the test.txt file. Since it is protected, it cannot be opened and Quick Look will show the progress indicator until a timeout has been reached. You can then unlock your device and repeat the preceding steps to open the file in Quick Look . AES encryption using JavaScript The Advanced Encryption Standard ( AES ) is a specification for the encryption of electronic data established by the U.S. NIST in 2001. This encryption algorithm is used for securing sensitive, but unclassified material by U.S. Government agencies. AES has been widely adopted by enterprise and has become a de facto encryption standard for many commercially sensitive transactions. This recipe discusses how AES can be implemented in JavaScript and incorporated into your Titanium Enterprise app. Getting ready This recipe uses the Ti.SlowAES CommonJS module as a wrapper around the SlowAES open source project. Installing these in your project is straightforward. Simply copy the SlowAES folder into the Resources folder of your project as shown in the following screenshot: How to do it... Once you have added the SlowAES folder to your project, next you need to create your application namespace in the app.js file and use require to import the module into your code as the following code snippet demonstrates: //Create our application namespace var my = { mod : require('SlowAES/Ti.SlowAES') }; Creating the recipe UI This recipe demonstrates the usage of the Ti.SlowAES CommonJS module through a sample app using two Ti.UI.TextField controls for input. First, a Ti.UI.Window is created to attach all UI elements. var win = Ti.UI.createWindow({ backgroundColor: '#fff', title: 'AES Crypto Example', barColor:'#000',layout:'vertical',fullscreen:false }); Next, a Ti.UI.TextField control is added to the Ti.UI.Window to gather the secret from the user. var txtSecret = Ti.UI.createTextField({ value:'DoNotTell',hintText:'Enter Secret', height:45, left:5, right:5, borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED }); win.add(txtSecret); Another Ti.UI.TextField is added to the Ti.UI.Window to gather the string to encrypt from the user. var txtToEncrypt = Ti.UI.createTextField({ value:'some information we want to encrypt', hintText:'Enter information to encrypt', height:45, left:5, right:5, borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED }); win.add(txtToEncrypt); Next a Ti.UI.Label is added to the Ti.UI.Window. This Ti.UI.Label will be used to display the encrypted value to the user. var encryptedLabel = Ti.UI.createLabel({ top:10, height:65, left:5, right:5,color:'#000', textAlign:'left',font:{fontSize:14} }); win.add(encryptedLabel); Finally a Ti.UI.Button is added to the Ti.UI.Window. This Ti.UI.Button will be used later in the recipe to perform the encryption test. var btnEncrypt = Ti.UI.createButton({ title:'Run Encryption Test', top:25, height:45, left:5, right:5 }); win.add(btnEncrypt); Encrypting and decrypting values This section demonstrates how to use the Ti.SlowAES module to use the secret entered in the txtSecret, Ti.UI.TextField to encrypt the contents of the txtToEncrypt, Ti.UI.TextField. Once completed, the encrypted value is then decrypted and compared against the original input. The results are displayed to the user in an alert message as shown in the following screenshots: The encryption test is performed when the click event for the btnEncrypt control is fired as shown in the following code snippet: btnEncrypt.addEventListener('click',function(x){ The first step in the encryption process is to create a new instance of the SlowAES module as shown in this code snippet. var crypto = new my.mod(); Next using the encrypt function, the secret provided in the txtSecret control is used to encrypt the value in the txtToEncrypt control. The encrypted results are then returned to the encryptedValue as demonstrated in the following statement: var encryptedValue = crypto.encrypt(txtToEncrypt.value,txtSecret.value); The encryptedLabel.text property is then updated to display the encrypted value to the user. encryptedLabel.text = 'Encrypted:' + encryptedValue; Next, the decrypt method is used to demonstrate how to decrypt the string value encrypted earlier. This method requires the encrypted string value and the secret as shown in the following snippet: var decryptedValue = crypto.decrypt(encryptedValue,txtSecret.value); Finally, the original input value is compared against the decrypted value to ensure our encryption test was successful. The results of this test are then displayed to the user through a message alert and the Titanium Studio console. alert((txtToEncrypt.value ===decryptedValue) ? 'Encryption Test successfully ran check console for details.': 'Test failed, please check console for details.'); });
Read more
  • 0
  • 0
  • 3442

article-image-basics-joomla-module-creation-and-creating-send-us-question-module
Packt
29 Jul 2010
9 min read
Save for later

The Basics of Joomla! Module Creation and Creating a "Send us a question" Module

Packt
29 Jul 2010
9 min read
(For more resources on Joomla!, see here.) Building a basic Joomla! module is not that difficult. In fact it's quite easy. Just stay with me, and we will divide the task into some easy-to-follow steps. First of all, we need to create a folder for our module, for example, mod_littlecontact. This folder is where we will place all the files necessary for our module. For example, one of the files we are going to need is the mod_littlecontact.php file, which is named exactly the same as the folder, but with a .php extension. Let's see what we need to put in it: <?phpdefined('_JEXEC') or die('Direct Access to this location is notallowed.');?><h1>Just a simple contact form!</h1> We will look at just the basics. First, defined('_JEXEC') checks whether the file has been included by Joomla! instead of being called directly. If it has been included by Joomla!, the _JEXEC constant would have been defined. With this PHP file created we need to create another file, an XML one this time. We will call it mod_littlecontact.xml; notice that, again, the name is the same as the folder one. Just create the file, and after that we will place the following contents in it: <?xml version="1.0" encoding="utf-8"?><install type="module" version="1.5.0"> <name>Little Contact Form</name> <author>Jose Argudo Blanco</author> <creationDate>2010</creationDate> <copyright>All rights reserved by Jose Argudo Blanco.</copyright> <license>GPL 2.0</license> <authorEmail>jose@joseargudo.com</authorEmail> <authorUrl>www.joseargudo.com</authorUrl> <version>1.0.0</version> <description>A simple contact form</description> <files> <filename module="mod_littlecontact"> mod_littlecontact.php</filename> </files></install> Most of the contents of this XML file are quite easy to follow and very self-explanatory. In the files section, we have included all the files necessary for our module. Notice that we do not include the XML file itself. With these two files created, we can give a try to this simple module. Copying this folder into our Joomla! modules folder won't work, as Joomla! requires us to install the extension through the Extensions | Install/Uninstall menu. So, what do we need to do? Just compress these two files into a ZIP file by using any tool of your liking. At the end we will need to have a mod_littlecontact.zip file with the following two files inside: mod_littlecontact.php mod_littlecontact.xml Installing our module is done exactly as with any other modules. Go to the administrator screen of our site, then go to the Extensions | Install/Uninstall menu, search and select the file, and then click on Upload File & Install button. If all goes OK, and it really should, we will be able to find our module listed in Extensions | Module Manager, as seen in the following screenshot: We can click in the module name, just as we would do with any of the others. If we enter the administration panel of the module we will see a screen very much like the other modules, as Joomla! standardizes this screen. Just take a look at the Details zone, which will look like the next screenshot: He re we can select the parameters we want, and enable the module. This time we will place it in the module_7 position of our template. Also note that the description is the one that we place in the module XML file: <description>A simple contact form</description> After we have enabled the module, we will be able to see it in the frontend, in the module position we have selected: There's not too much for now, but it's working! Now we will enhance it and convert it into a contact form. Note that now that we have installed our module, a new folder will have been created into our Joomla! installation. We can find this folder in the modules folder, it will be called mod_littlecontact. So now we have this structure on our Joomla! Site: modules/ mod_littlecontact/ mod_littlecontact.php mod_littlecontact.xml As the module is already installed, we can modify these files, and we will be able to see the changes without needing to reinstall it. We have just accomplished our first step; the basics are there, and now we can concentrate on making our modifications. Creating a "Send us a question" module One of the first things we are going to create is an empty index.html file; this will be used so that no one can take a look at the folder structure for the module. For example, imagine that our site is installed in http://wayofthewebninja.com. If we go to http://wayofthewebninja.com/modules/mod_littlecontact/ we will see something like the next image: If we try to click on mod_littlecontact.php, we will see the following phrase: Direct Access to this location is not allowed. That's because the code we added to our file is as follows: <?phpdefined('_JEXEC') or die('Direct Access to this location is notallowed.');?> Of course, we don't want people to be able to see which files we are using for our module. For this place, we used the empty index.html file mentioned in the modules/mod_littlecontact folder. This way, if anyone tries to go to http://wayofthewebninja.com/modules/mod_ littlecontact/, they will see only an empty screen. Good, now note that when we add any file, we need to reflect it on the mod_littlecontact.xml file in the files section: <files> <filename module="mod_littlecontact">mod_littlecontact.php</filename> <filename>index.html</filename></files> This way, when we pack the file for install, the installation process will take this file into account, otherwise it will be left out. Once we have done this, we are going to create another file, a CSS one this time, so we can put our styles in it. For this we are going to first create a new folder, also called css. It will be placed in modules/mod_littlecontact/. Inside that folder we will create a file called styles.css; this file also needs to be declared in the XML: <filename>css/styles.css</filename> In this modules/mod_littlecontact/css/styles.css file we are going to place the following code: #littlecontact h1{ font-size: 18px; border-bottom: 1px solid #ffffff;} But then, if we are to apply these styles, we need to load this CSS file. How are we going to do this? Open the modules/mod_littlecontact/mod_littlecontact.php file and modify it as follows: <?phpdefined('_JEXEC') or die('Direct Access to this location is notallowed.');JHTML::stylesheet('styles.css','modules/mod_littlecontact/css/');?><div id="littlecontact"> <h1>Just a simple contact form!</h1></div> There's not much change here; we have enveloped our previous content in a DIV, with the littlecontact ID, so that we can target our styles. This is the easy part, but there's also an important one, shown as follows: JHTML::stylesheet('styles.css','modules/mod_littlecontact/css/'); We are using the JHTML::stylesheet method to create a link, in our header section, to our CSS file. In fact, if we check the source code on our frontend, we will see: <link rel="stylesheet" href="/modules/mod_littlecontact/css/styles.css" type="text/css" /> This way our stylesheet will be loaded, and our module will look like the next screenshot: As we can see, our styles have been applied. The JHTML::stylesheet method is quite easy to use, the first parameter being the file and the second one being the path to the file. Now we are going to prepare our simple form. Again we will modify our mod_littlecontact.php file, and now it will look more like the following: <?phpdefined('_JEXEC') or die('Direct Access to this location is notallowed.');JHTML::stylesheet('styles.css','modules/mod_littlecontact/css/');?><div id="littlecontact"> <h1>Just a simple contact form!</h1> <form action="index.php" method="post" id="sc_form"> <label>Your name:</label><br/> <input type="text" name="your_name" value="" size="40" class="sc_input"/><br/><br/> <label>Your question:</label><br/> <textarea name="your_question" class="sc_input" rows="5" cols="30"></textarea><br/><br/> <input type="submit" name="send" value="Send" class="sc_button" /> </form></div> This is a common HTML form. We need some styling here, just to make it look good. Let's make the following minimal changes to our styles.css file: #littlecontact h1{ font-size: 18px; border-bottom: 1px solid #ffffff; margin-bottom: 15px;}.sc_input{ border: 1px solid #3A362F;}.sc_button{ background-color: #3A362F; border: 0; color: #ffffff; padding: 5px;} Most styles are new, and modifications to previous h1 styling have been marked. With this minimal change our module looks a bit better. You can see it in the following screenshot:
Read more
  • 0
  • 0
  • 3440
article-image-jquery-ui-themes-using-themeroller
Packt
04 Aug 2011
8 min read
Save for later

jQuery UI Themes: Using the ThemeRoller

Packt
04 Aug 2011
8 min read
jQuery UI Themes Beginner's Guide Create new themes for your JQuery site with this step-by-step guide ThemeRoller basics Before we start using the ThemeRoller application to design and build our own themes, we'll take a quick look at what makes it such a handy tool. There is a lot more to the ThemeRoller than simply changing themes—we also use it to build them. You can think of it as an IDE for jQuery UI themes. Instant feedback What makes the ThemeRoller application such a powerful development tool is the speed with which you get feedback to changes made in the theme design. Any change made in the ThemeRoller is instantaneously reflected in the sample widgets provided on the page. For instance, if I were to change a font setting, that change would be reflected immediately in the sample widgets provided on the same page. There is no need to update the application you're building to see the results of small adjustments made to theme style settings. The same is true of prepackaged themes in the ThemeRoller gallery. Selecting a theme will apply it to the same widgets - you get immediate feedback. This is very helpful in deciding on prepackaged themes. If you can see how it looks with jQuery UI widgets right away, that may dissuade you from using the theme or it may close the deal. The idea behind this feedback mechanism offered by the ThemeRoller is a sped-up development cycle. Eliminating several steps when developing anything, themes included, is a welcome feature. The dev tool The ThemeRoller dev tool is a simple bookmarket for Firefox that brings the entire ThemeRoller application into any page with jQuery UI widgets. The benefit of the dev tool is that it allows you to see immediate theme changes in the context of the application you're building. If you use the ThemeRoller application from the jQuery UI website, you can only see changes as they apply to the sample widgets provided. This can give you a better idea of what the theme changes will look like on a finished product. There are some limitations to using the dev tool though. If you're developing your application locally, not on a development server, you can't use the dev tool due to security restrictions. The dev tool is better suited for viewing changes to themes, or viewing different themes entirely, on a deployed user interface. Having said that, if you're designing a user interface with several collaborators, you might have a remote development server. In this scenario, the dev tool suits its name. Portability The ThemeRoller application is portable in more ways than one. The dev tool for Firefox allows us to use the application within any jQuery UI application. This means that we can design and tweak our jQuery UI themes as we build the widgets. This portability between applications means that we can build a single theme that works for a suite of applications, or a product line, if we're so inclined. We can also use the ThemeRoller application directly from the jQueryUI website. This is handy if we don't have any widgets built or if you're trying jQuery UI out for the first time and just want to browse the wide selection of prepackaged themes. Whatever approach you take, the application is the same and will always be consistent, as it is a hosted application. You don't need to concern yourself with installing an IDE for theme authors to collaborate with. The ThemeRoller application is available wherever they are. ThemeRoller gallery It is nice to have a wide variety of prepackaged themes to choose from. It isn't all that helpful if you can't see how they look. The ThemeRoller application has a gallery where we can not only browse prepackaged themes but also take them for a test drive. This section is about using the ThemeRoller gallery to view themes and get a feel of the variety available to us. Viewing themes The ThemeRoller application doesn't hide anything about the prepackaged themes in the gallery. When we preview a theme, we get to see how it looks when applied to widgets. The theme gallery even gives us a thumbnail in the browser to show a bird's eye view of the theme. So if you see a lot of black and you're looking for something bright, you don't need to bother selecting it to see how the widgets look with it. Time for action - previewing a theme It's time for us to preview a jQuery UI theme before we actually download it. We can get an idea of what a theme in the ThemeRoller gallery will look like when applied to widgets: Point your web browser to http://jqueryui.com/themeroller/. Select the Gallery tab in the ThemeRoller section on the right-hand side. Move your mouse pointer over any theme in the gallery. A visual indicator will be displayed. Select the theme thumbnail:   What just happened? We've just selected a theme to preview from the ThemeRoller gallery. You'll notice that all the sample widgets to the right are instantly updated with the new theme. If we wanted to, we could change our theme selection and the sample widgets are once again updated with the theme changes. You'll notice that once you make a theme selection, the URL in your address bar is now long and ugly. These are the individual theme settings for the chosen theme being passed to the ThemeRoller page with the sample widgets. You'll also notice that the theme selection on the left-hand side of the page isn't preserved. This is because we're passing individual theme settings and not the name of the theme itself, for example, instancetheme=darkness. We'll see why this distinction is important in a little bit. Downloading themes Once you've selected a theme from the gallery and you're happy with how it looks, it is time to download it and use it with your jQuery UI project. Downloading a theme is easy—each prepackaged theme has a download button that will take you to the jQuery UI download page. If we wanted to, we could download all themes in a single package to experiment with, locally. This would also eliminate the need for the ThemeRoller application, which you probably don't want to do. Time for action - downloading a theme The gallery is a nice way to preview a theme, but now we want to use it in our application. To do this, we need to download it. This is similar to downloading the jQuery UI toolkit: Point your web browser to http://jqueryui.com/themeroller/. Select the Gallery tab in the ThemeRoller section on the left-hand side. Find a theme you wish to download. Click on the Download button underneath the theme thumbnail. This will bring you to the jQuery UI download page. Notice that your chosen theme is selected on the right-hand side of the page. Click on the Download button to download your theme: What just happened? We've just selected a prepackaged theme from the ThemeRoller gallery and downloaded it. In fact, you just downloaded jQuery UI again. The difference being, the downloaded ZIP archive contains the theme you selected from the gallery. The same principles apply for extracting the archive and using your theme with your jQuery UI application. The downside is that if you're downloading a theme, chances are you already have a jQuery UI application under development. In this case, downloading jQuery UI JavaScript files is redundant. However, there is no easy way around this. This is one of the drawbacks to having a useful tool available to us—a minor drawback at that. If you're only interested in the theme, you simply need to extract the theme folder from the ZIP archive and copy it to your jQuery UI application directory. You then need to update your path in your HTML in including the appropriate CSS file. You'll also notice that after clicking on the Download button from the theme gallery, you're brought to the download page with an ugly URL. That is, you'll see something like /download/?themeParams=%3FffDefault instead of just /download. This is a requirement of the ThemeRoller application that allows developers to edit existing themes or to roll their own. Without these parameters, we wouldn't be able to download themes we have made changes to. The jQuery UI download page also includes an Advanced Settings section that is hidden by default. This is because you rarely need to use it. It allows you to set the CSS scope for your theme, useful if you're using multiple themes in a single user interface. This isn't a recommended practice; the key idea behind jQuery UI themes is consistency. The advanced settings also lets you change the name of the downloaded theme folder. This can be useful if you plan on changing your theme later, but you can always rename the folder after downloading it.
Read more
  • 0
  • 0
  • 3440

article-image-overview-complex-event-processing
Packt
07 May 2013
11 min read
Save for later

An Overview of Complex Event Processing

Packt
07 May 2013
11 min read
(For more resources related to this topic, see here.) What is event processing? In the world around us, every second of every minute of every hour, the human brain is bombarded with a limitless number of things that happen either at the same time or sequentially, or in a totally and seemingly erratic way that may not make sense immediately but as more of these things happen, we can start to understand their relevance and importance. For example, we hear cheering in the distance, we see balloons flying in the air, music starts to play, police cars and trucks appear pulling brightly covered trailers with puppets and people waving on them, followed by ambulances, and today's date is July 4th. Individually, these events could mean anything, but together? It's probably an Independence Day Carnival Parade! Our brain can easily determine this fact in the blink of an eye" and while not overly simple to define in computing terms, we could describe a "Parade Event Pattern" as follows: One (or more) police cars + followed/preceded by, or adjacent to + one (or more) carnival trucks + followed/preceded by, or adjacent to + one (or more waving people) + followed/preceded by, or adjacent to + one (or more emergency vehicles) + where music can be heard + and today's date is 4th July Your brain is not restricted to sending information and just waiting until there is a response, or forced into following a series of fixed steps to get something done. As with this example, it is able to take the events happening now, their relevance to additional external factors such as today's anniversary date and understand a "parade" event pattern. So as you learn more about Complex Event Processing, we focus on how this technology can take continuously flowing, never-ending information, from a potentially unlimited number of different places, and immediately understand how it relates to things happening right now and in the very near future, commonly known as Real-Time Situation Awareness. Relating this to a business in computing terms The problem now in the world of computers is the proliferation of data. Information arrives from many different systems, in vast quantities, at different times, at different speeds, some of importance now to certain other systems, people or processes, and some stored for later recovery and determination. Why the proliferation now? There are many issues involved, but here are just a few major ones: The cost of computer power and sophisticated environmental sensor devices has become less expensive Networking capacities increase and become more intelligent The many different functional computing silos (finance systems, manufacturing systems, sales systems, and so on) are broken down, rewritten, enabling processes that can span more and more business demands New computer solution demands expand beyond the enterprise to include partners, customers so more and more data sources and other inputs are brought online Computing technology architectures such as Service Orientated Architecture (SOA) becomes increasingly successful, resulting in an ever more elaborate ecosystem of re-usable services A Big Data explosion, a term now used widely for information that arrives in high volumes, with extreme velocity, and in a wide variety of mostly unstructured formats emanating from social media sites, cell phones, and many other sources A growing demand from businesses that expect their Information Technology (IT) teams to respond to market situations much more effectively in real time As we evolve and the complexity of these systems "pour" more and more huge volumes of information at computer applications, we are reaching a "tipping point" where traditional point-to-point or request-reply-based solutions of the world break down and become unmaintainable and not extendable. A company business can be influenced instantaneously from things (events) that can happen, not only in the "cozy" understandable world within its own environment but also from activities (events) from beyond, such as from "the Internet of things"—realtime sensor device that can measure and report on a multitude of situations, including "the impending danger from a sudden rise in temperature in a food storage facility" or "the global positioning system location of a shipping container which is having an unauthorized opening with movement detection sensed from within". Immediate impact to a company's business can also come appear "out of nowhere" emanating from a change in global business conditions indicated from the everexpanding social media outlets, for example, Twitter, instant messaging, and so on. Millions of people at the same time can all comment on the poor condition of a new product, highlighting an immediate need to change a product design. This will inevitably affect profits and will probably significantly affect the value of the business. So companies are now inevitably being manipulated by a wide range of both understood and misunderstood events. In the past, probably going back over 15 years ago, business applications have had to conform to the methodologies, structure, and interfaces from the then available computing technologies (such as databases) where information must be inserted and statically placed. Only after this can users then analyze and respond. Traditional JEE Application Servers were generally implemented, expecting a client application to send an initial request and will then only process that request through, in most cases a significant amount of logic code, before it can respond back to the client. While these technologies enable, and will continue to provide benefit in more batch-orientated, less real-time approaches, newer lower latency and faster in-memory middleware products are now available. Event-Driven (Architecture) based systems are intrinsically smarter, or better "equipped" to handle these types of situations, processing an entire business infrastructure as events that can be immediately interpreted and handled, spanning across the many departmental "silos" such as finance, manufacturing, and sales. These types of systems are also context aware and execute when they detect changes in the environment or business world, rather than occurring on a predefined (nightly) schedule or requiring someone to initiate an execution. As the problems associated with Big Data grow substantially over the coming years in terms of the capture, management, and the ability to process the information within a tolerable amount of time, Event-Driven technologies (specifically Complex Event Processing) can provide Fast Data capabilities to apply a greater level of "intelligence" and decisioning to the originating data streams much closer to the "point of occurrence". So the benefits of an Event-Driven technology approach is to turn that proliferation of data into real-time knowledge by firstly representing events (things that happen from anywhere) in standard ways, providing an ability to factor out events, route events, filter events, aggregate events, and correlate events intelligently, so that in most cases fragmented events can be evolved into holistic, solid, understandable business events, enabling the business to better view, control, and adapt to situations relatively instantaneously. Use case: A solution for customer problems So how are Complex Event Processing Platforms used now to solve business problems? Certainly over the past few years, this technology is being used across most, if not all, of the different types of industries. The financial services capital markets companies are using this technology for real-time algorithmic trading and real-time risk management types of solutions. As the stock markets stream their endless financial instrument data with values which can instantly fluctuate, there is an ever growing need to effectively handle this huge volume of information, understand its impact and potential risk, and then react as quickly as possible. The better the capability to evaluate and predict the consequences of the information, and the quicker the ability to respond to the results of this analysis, the more successful the business and the more money that can be made with less exposure to business risks and threats. This type of real-time trading information can be usually visualized using heat maps and scatter charts. In the Electricity industry, customers are using the Complex Event Processing (CEP) platform for many new types of applications, which include Smart Meter, Smart Grid, and outage detection monitoring solutions. Sophisticated Demand Response (DR) solutions bring together system operators and the power generation companies, who contract with energy management and monitoring companies to provide energy usage load reduction services on demand. These technology companies that are using CEP-based applications contract with commercial and industrial businesses that are large consumers of energy, whom agree to curtail energy usage on demand. Streaming event devices are installed at client locations to measure energy usage and, in some cases, proactively control the load using continuous energy demand and usage data at minute or, even second, intervals. The generated profit revenue received from system operators is then passed back to the clients, relative to the number of associated load reduction dispatches. Handling real-time events has a long history in the telecommunications industry, such as those generated by the various devices on the network, events from mobile phones, or perhaps streaming Call Detail Record (CDR) events indicating the time of calls made and whether some of these calls failed. Complex Event Processing platforms provide the technology for many new applications and solutions in this domain. As in other industries, Event-Driven platforms have a broad base of possible implementations. Some businesses have created powerful network management and monitoring solutions, which can detect hardware failure-related events continuing over certain time periods, or situations where equipment has not been issuing events for some time and in these circumstances alert messages are distributed and escalated. In the context of an enterprise-level mobile telecommunication IT infrastructure, there are many different applications coming from many different suppliers. When the overall performance is not immediately meeting expectations, it's not easy to identify which component is the offending issue in the supply chain. Therefore these next-generation management and monitoring applications (based on Complex Event Processing) provide the capabilities to show the complete, holistic "picture", providing full visibility to the situation of a business through flexibility and fully integrated features, enabling agility for the infrastructure to react quickly to changing scenarios, and providing full operability enabled by a solution designed to meet business needs. A very powerful capability of Complex Event Processing platforms which is being leveraged in the Transportation, Telecommunications, and Public Sector domain is real-time integrated spatial analysis. A business can use this technology in applications where there is the need to monitor the movements of its assets and resources. Using, for example, GPS (global positioning systems) the movement patterns of someone, or something can be tracked in real time as it passes through boundary points (such as security checkpoints in an airport) to identify its route and, to some extent, predict where this person or object may subsequently move next. Also, this capability can be used to analyze a current position and its relationship to geofenced areas. A geofenced area being the definition of a geographical shape (polygon) defined or declared by a series of spatial coordinates. When a resource gets near, inside, or enters and exits the geofenced area, various actions can be immediately performed, such as a warning message of an imminent exposure to a dangerous natural disaster, or offering a big discount on a second coffee at the person's current location or soon to be, position, based on his or her current movement pattern. First Responder emergency services solutions can use integrated spatial technologies to not only monitor a fire or hundreds of simultaneous fires, but also dynamically track the movement on the fire, affected by weather conditions (wind) or igniting hazardous materials. These types of systems can evaluate immediately the relevance, importance, and applicability of all of the related assets (fire engines, police vehicles, and so on) close to these areas. For example, if a fireman does not move in certain number of seconds when close to a fire, this could indicate a serious life threatening situation. There are many other types of business solution implementations using Complex Event Processing platforms that range from online retail monitoring systems, real-time data center infrastructure management, fleet vehicle transportation monitoring, traffic flow monitoring with variable toll charging and speed control, oil fields and rig monitoring/automation, and a host of real-time sensing device opportunities, where these devices can monitor the environment inside shipping containers, or air pollution situations. The scope and different type of applications that can now benefit from using Complex Event Processing technologies are evolving just as quickly as the world is changing, with a growi ng need to predict and pre-empt and in, some cases, prevent situations from even happening.
Read more
  • 0
  • 0
  • 3438
Modal Close icon
Modal Close icon