Interactive Construction:
Interactive Fabrication of Functional Mechanical Devices
Figure 1: (a) Constructable users interact by drafting directly on the workpiece with hand-held lasers. (b) Here the user sketches a finger joint across two objects (c) The system responds by cutting the desired joint using the cutting laser. (d) Constructable allows creating precise and functional mechanical objects, such as this simple motorized vehicle.
Personal fabrication tools, such as laser cutters and 3D printers allow users to create precise objects quickly. However, working through a CAD system removes users from the workpiece. Recent interactive fabrication tools reintroduce this directness, but at the expense of precision.
In this paper, we introduce constructable, an interactive drafting table that produces precise physical output in every step. Users interact by drafting directly on the workpiece using a hand-held laser pointer. The system tracks the pointer, beautifies its path, and implements its effect by cutting the workpiece using a fast high-powered laser cutter.
Constructable achieves precision through tool-specific constraints, user-defined sketch lines, and by using the laser cutter itself for all visual feedback, rather than using a screen or projection. We demonstrate how Constructable allows creating simple but functional devices, including a simple gearbox, that cannot be created with traditional interactive fabrication tools.
Introduction
Rapid prototyping/personal fabrication tools, such as 3D printers and computer controlled milling machines help users create one-off prototypes rapidly.
The process places CAD software at the frontend to personal fabrication tools. The use of CAD provides three main benefits over traditional woodworking tools, such as saws and wood chisels: (1) Fast interaction, it is generally faster to describe what to do to a software program than to operate an actual mechanical tool. (2) Trial-and-error: Users can undo mistakes and even selectively correct flaws. (3) Precision: constructions aids, such as constraints allow users to precisely manufacture pieces that can perform mechanical functions.
On the flipside, the transition from traditional tools to personal fabrication tools means that all editing is now done on a computer screen, which removes users from the workpiece and prevents users from refining their design interactively along the way [31].
Interactive Fabrication
Interactive fabrication systems address this by letting users once again work directly with the workpiece [31]. CopyCAD [8], for example, allows users to draw on the workpiece.
A key element of interactive fabrication systems is that they provide output to users not at the end of the process, but after every editing step (e.g., Shaper [31]). This allows users to (1) validate their designs earlier and (2) build subsequent work steps on the result of earlier steps. The related work suggests that this offers value to artists and designers [31], as their creative process is often inspired by seeing the partially completed workpiece. We argue that similar benefits can be achieved when working on technical projects.
The transition to interactive fabrication, however, comes at a cost. First, since editing is now intertwined with fabrication, editing becomes slower, because users have to repeatedly wait for the fabrication engine to finish. Second, as we give up on traditional tools like CAD, users lose the precision required to create functional devices.
In this paper, we attempt to put these qualities back into interactive fabrication, moving it in the direction of what we call interactive construction. We present constructable, a laser cutter-based interactive construction system that allows users to construct functional mechanical devices, while maintaining the immediateness of an interactive fabrication system.
Constructable
Constructable is a drafting table that produces physical output in every step. As illustrated by Figure 1, all interaction in constructable takes place on the workpiece, mediated through low-power hand-held laser pointers, which we call proxy lasers or simply tools. In the shown example, the user uses the finger joint tool to add finger joints between two pieces by crossing the two involved edges.
Proxy lasers are too weak to affect the work piece. To make the interaction ‘real’, constructable tracks proxy laser interactions using a camera mounted above (Figure 1b), reconstructs the tool’s path, transforms it using a constraint set defined by the current tool, and implements the effect using its high-powered cutting laser (Figure 1c). Since all key elements were constructed in the context of constraints, we obtain fully functional mechanical devices, such as the simple motorized vehicle shown in Figure 1d.
The combination of proxy laser and cutting laser is one of the key ideas behind our system, because it allows users to work faster and more interactively than the interactive fabrication systems in the related work. The reason is that the manipulation of materials that are durable enough for making functional mechanical devices requires a high-powered tool. These, however, require safety measures, such as our glass enclosure. Opening and closing the enclosure for each interaction takes too long, but by letting users point at the workpiece through the safety enclosure, constructable allows user’s attention to remain on the workpiece at all times, despite the enclosure. As intended, users witness how the workpiece changes with their every interaction first hand and not mediated by a screen or projector.
Constructable achieves its other main design objective, i.e., precision, using a system of constraints implemented by the individual proxy lasers.
Proxy lasers
Figure 2 provides a closer look at the proxy lasers. Each proxy laser features three barrel buttons (Figure 2c). While held depressed, the middle button activates the beam, allowing the system and the user to see where the tool is pointed [21]. The visual feedback allows users to determine a starting point with precision before starting to cut. It thereby implements the tracking state of its three-state model [5].
The other two buttons trigger the tool’s two modes of operation. The cut button allows cutting a tool-specific shape, such as a circle for the circle tool. The sketch line button creates the same shape, but etches it as a shallow dashed line into the surface of the material. Sketch lines have no direct impact on the mechanics of the workpiece, but instead serve as alignment aids that magnetically attract subsequent cuts (alignment lines [3]).
All tools explain themselves exclusively through the cut or sketch line they produce and there is no further visual feedback, i.e., no screen or projector. Since all output is created using the laser cutter itself, constructable’s geometry output is extremely precise.
Figure 2: (a, b) Constructable offers 15 different proxy lasers and an undo button. (c) Each proxy-laser offers three barrel buttons.
Creating, Selecting, copying, and pasting using tools
Constructable achieves precision by means of sketch lines and by implementing constraints into every proxy laser. Constraints differ between tools.
Creating: Polyline, Circle, and Freehand are constructable’s tools for creating objects from scratch. These tools are only moderately constrained. The circle tool, for example, always produces a perfect circle, but diameter and location remain freehand. The freehand tool is not subject to any constraints.
Most of constructable’s tools connect to or extend an existing object and this spatial relationship adds constraints. Users establish these constraints by selecting one or more existing objects. The finger joint tool, for example, snaps to existing lines.
Selecting: As illustrated by Figure 3, users select (a) a surface by clicking into it, (b) an edge by crossing it [2], and (c) a point by drawing a pigtail close to it [12]. We designed this selection mechanism so as to extend seamlessly to multiple objects. Users select (d) multiple surfaces by drawing a path across, (e) multiple edges by crossing multiple edges, and (f) multiple points as a sequence of multiple pigtails.
Figure 3: Constructable allows users to select (a) objects by pointing, (b) lines by crossing, and (c) points with pigtails. (d-f) To allow for fast selection, all selection gestures can be extended across multiple objects, lines, and points.
Pasting: A range of tools, such as the copy tool, results in the creation of new objects. The size and shape of a new object is determined implicitly, e.g., by the object being copied and does not require or allow for user input. However, to allow users to optimize material usage, we let users show constructable where to create it. As illustrated by Figure 4, users point constructable to available material by drawing a directional cropmark (see also [19]). The orientation of the cropmark specifies the orientation of the pasted object, allowing users to optimize for material use.
Figure 4: Users paste an object by drawing a crop-mark. Constructable places the object into the “inside” of the cropmark. Cropmarks allow users to place objects carefully into available space while preventing them from cutting into adjacent contents.
Walkthrough: Constructing a Device
In the following, we illustrate constructable’s tools at the example of the simple motorized vehicle that we had briefly touched upon in Figure 1. Figure 5 shows the final outcome and the pieces required to produce it.
Figure 5: (a-c) The gearbox in different states of assembly, for use in (d) a simple motorized vehicle.
We start by creating the housing (Figure 6). (a) We use the polyline tool to sketch the rectangular base. (b) Using the sketch line button on the scale tool we create a sketch line rectangle around the base—this sets the height of the walls. (c) By crossing the north edge of the base with the Extrude tool, we create the first wall segment. (d) For efficiency, we create the remaining three walls using a single long stroke that extrudes the base east, south, and west. There is no limit on concatenating, so we could have also extruded all four walls in a single stroke. (e and f) To allow us to assemble the housing later, we add finger joints. We connect the walls by crossing pairs of respective edges using the finger joint tool. (g) Finally, we assemble the box by connecting the finger joints.
Figure 6: Interactively constructing the housing for the motorized vehicle and gearbox.
Figure 7 shows how we add gearbox and wheels. (a) To make sure that we end up with straight axles we draw three sketch lines using the polyline tool. (b) We create the first axle hole using the hole tool, the location of which snaps to the intersection of the two sketch lines located close by. (c) We draw all remaining axle holes using a single stroke concatenating multiple pigtails.
(d) We create the first pair of gears by selecting two axle holes, define the transmission ratio by marking the point where we want the two gears to meet, and show constructable where to create the gears using a cropmark. We create the second set of gears accordingly.   (g) We create a second wheel by copying the first one using the copy tool.
We are now done creating our parts. We remove them from the machine and assemble them, resulting in the vehicle shown in Figure 5.
The device is mechanically functional, because every mechanical connection was created using tools that embody appropriate constraints.
Figure 7: Continuing the previous example, we add axles, a two-stage gearbox, and wheels.
Decorative functionality
While constructable was designed with the goal of supporting interactive construction, its underlying concept of tools allows us to integrate form-giving (Figure 8) and decorative functionality as well (Figure 9).
Figure 8: Creating a wooden booklet sleeve by (a) drawing the cover with the polyline tool, then (b) smoothing the corners with the round tool, and (c) making the wood flexible using the bend tool [1].
Figure 9 illustrates how we apply a logo to the housing of our motorized vehicle, á la CopyCAD [8]. (a) Continuing our earlier example, we place the housing of our motorized vehicle back into the machine, and position a photo with the desired logo on top of it. (b) We wave the rub-on tool across those areas of the photo that we want to transfer. (c) We take the photo back out, and as we close the lid, constructable engraves the logo into the housing.
Figure 9: Adding a decorative logo onto the side of the motorized vehicle using the rub-on tool.
Similarly, the trace tool cuts the contours of a physical object into the workpiece. Figure 10 shows how to use this to create a holder for two paint jars.
Figure 10: Creating a holder for two paint jars by (a) selecting physical objects inside the cutter using the trace tool, (b) After removing the physical objects constructable cuts.
Finally, we can use the freehand tool to create unconstrained freehand lines and cuts (Figure 11).
Figure 11: Sketching using the freehand tool.
Trial-and-error support using “undo” tools
Finally, constructable offers basic support for trial-and- error by providing an approximation of “undo” tools. Since physical cuts cannot be undone, constructable’s “undo” tools instead refabricate the object — they create a copy that does not have the cut. Users apply the tool by crossing the cuts they want removed; they then paste the newly restored object.
While the primary purpose of the tool is to repair and undo, the way it achieves this is by uniting two objects and copy-ing the result. Since this functionality is useful beyond undo, we ended up giving the tool the name union tool.
In practice, any tool that unites two objects can be used as an undo tool. Figure 12 shows the butterfly joint tool, which connects two objects using a butterfly connector. This tool produces a butterfly-shaped hole across the cut and lets users paste a matching butterfly-shaped connector. Users repair the cut on assembly by placing the connector into the hole—it sits tight enough to create a lasting connection. While the union tool obviously creates the stronger connection, a butterfly joint consumes less material.
Figure 12: Undoing a cut by re-uniting the pieces using the butterfly tool.
Benefits and Limitations, Summary of the Design
In the above walkthrough, we demonstrated interactive construction using constructable. We showed how constructable allows to interactively construct a functional mechanical device by bringing some of the key qualities of CAD-based personal fabrication into interactive fabrication.
Precise input and output
Constructable achieves the precision required to make functional mechanical devices as follows:
Precise input: Even though all input to constructable is mediated through a hand-held tool, the resulting jerkiness never interfered with precision because all relevant parame- ters are appropriately constrained. Only parameters with no functional implications, such as the size of the base of the motorized vehicle, were defined free hand.
Constructable uses three types of constraints: (1) Each tool implements constraints; the polyline tool, for example, draws only rectilinear contents. (2) Sketch lines allow users to add constraints explicitly. (3) A special class of tools that create connections, such as finger joints create both halves of the connection at once. As a result, finger joints always fit perfectly even though they involve two parts. The gear tool is based on the same concept and one might say that it connects two axles.
Precise output: As mentioned earlier, all tools explain themselves exclusively through the cut or sketch line they produce. Since this allows all output to be created using the laser cutter itself, constructable’s geometry output is extremely precise. This offers orders of magnitude higher resolution than projection and is never subject to calibration issues.
No projection
An early version of our system did feature a projector, similar to several systems in the related work, such as CopyCAD [8]. Letting go of it not only increased precision, but also made sure we directed users’ attention at the work-piece at all times, rather than at a projection collocated with the workpiece.
A side effect of not having a computer display meant that we had to eliminate all hidden state and modes, because there was no way to keep users informed about them. This led us to design the proxy laser model, in which the current set of constraints is represented solely by which physical device the user is currently holding.
As another side effect of using the cutter as the sole visual feedback device, sketch lines became permanent. While users can erase sketch lines by replicating the final object using the unite tool, we think that users will typically choose to leave these lines in, the same way that designers leave sketch lines in to illustrate their process or even because they are esthetically pleasing [4].
Trial-and-error using “undo” tools
We implemented trial-and-error using special “undo” functions, such as the union and butterfly joint tool that allow users to re-create the previous state of an object by refabricating it.
Fast interaction via the proxy laser mechanism
As mentioned earlier, constructable achieves fast interaction using the proxy laser mechanism, i.e., drawing with low-power laser tools, the effect of which is implemented by a high-power cutting laser. We found the resulting interaction to invite a powerful conceptual model, namely that the cutting laser amplifies the proxy laser, similar to how power brakes and power steering amplify the driver’s muscle strength. We plan to develop this notion further in future versions of constructable, with the ultimate goal of causing at least the freehand proxy laser to invite the interpretation that it itself is cutting.
Limitations
Like any tool, constructable is useful for some design problems and less so for others. While constructable extends the range of problems that can be tackled interactively, it is obviously not a CAD system. As with traditional wood-working tools, some types of projects can be tackled tool-in-hand, while more advanced problems require users to sit down with a piece of paper first. The same way that saw and wood chisel cannot replace a detailed design process, constructable cannot replace CAD.
Another limitation is that all construction with constructable is inherently scale 1:1 and constructable offers no way of inspecting a detail in magnification. Similar to working with traditional woodworking tools, this limits users to projects that fit a particular scale.
Finally, constructable was not designed with walk-up use in mind. While some tools, such as the finger joint tool have the potential to make complex construction elements accessible to inexperienced users, mechanical construction in general does require know-how. Rather than addressing first time users, we designed the majority of constructable’s tools so as to be generic in nature, to apply to each other, and thereby allow for a wide range of constructions.
Ergonomic: The Drafting Table Form Factor
While constructable is primarily about constructive functionality, we made some observations on ergonomics.
While we initially perceived it mostly as a design hurdle, the laser cutter’s glass cover turned out to become one of the key elements creating the affordance of our system. (Figure 13a). By allowing users to rest their body weight on the glass, it allows users to get even closer to the workpiece without worrying about interfering with it. Furthermore, we found ourselves resting proxy lasers on the glass while drawing (Figure 13b), which adds substantial stability, making the interaction even more precise.
Figure 13: (a) The glass cover supports users’ weight, allowing them to get close to the workpiece. (b) Resting proxy lasers onto the glass allows for precise interaction.
To invite this interpretation and posture, we positioned the proxy laser tools as shown in Figure 13c. This allows users to reach tools without lifting their arm, but instead pivoting around their elbows similar to the Lagoon in Alias Sketchbook [6].
We found all of the above to invite the interpretation of constructable as a drafting table, the “drawing” on which is the actual physical object itself. We plan on building on this interpretation in future versions by tilting the glass cover slightly towards the user (e.g., as in ActiveDesk [7]).
Contribution
The main contribution of this paper is the concept of interactive construction, which we support with the functional system prototype constructable. Our demo scenarios illustrate how users can create functional mechanical devices, which exceeds the complexity of examples created in the interactive fabrication literature. We are thus primarily making a systems contribution.
In addition, our system contains a series of novel elements, including (a) the proxy laser mechanism, i.e., drawing with low-power laser tools, the effect of which is implemented by a high-power cutting laser, (b) the use of the laser cutter as a super high precision display, replacing projection, and (c) the notion of undoing a physically destructive action by refabricating the broken piece.
Implementation
Figure 14 shows how constructable processes proxy laser input in order to generate cutting laser output.
Figure 14: Data processing flow in constructable.
Sensing
Constructable observes the workpiece using a web cam (MS Lifecam, 844x448px, 30 fps) and extracts the dot produced by the proxy-lasers using color tracking. Constructable then smoothes tool paths using a Kalman Filter and performs shape recognition on paths using PaleoSketch [25] before applying the geometric operations and spatial constraints defined by the tool.
At this point, constructable records the interaction history, which it uses to support undo and selective repairs using the union tool.
Output to the laser cutter
Constructable now outputs the shape to the laser cutter, currently a Universal PLS6.150D. Using the OpenDraw API, Constructable draws the shape into an OpenDraw document, which it sends to the cutter using the printer interface. As required by Universal laser cutter systems, constructable encodes the necessary meta-information into the color of the respective line, i.e., cutting-depth (mm), laser power (percentage), and speed (percentage). A red 0pt line, for example, causes the laser to cut, while green is used to create a shallow, low-power sketch line. Constructable sends all communication using the Open Sound Protocol, which makes it easy to adapt the system to other hardware components, such as a different laser cutter model.
Remixing: using physical objects as a reference
Constructable captures physical objects using the same camera that tracks the laser dots. A bar of fluorescent light mounted inside the cutter supports this by providing homogeneous, reflection-free illumination of the workpiece. An IR rangefinder sensor informs the system when the lid is open.
Proxy lasers
In order to retrieve the constraint set represented by the current tool, constructable determines which tool is in use using mechanical switches, one of which is installed in each tool holder (similar to pen “recognition” in SmartBoards, smarttech.com). This bypass allows us to implement all proxy lasers using a single type of off-the-shelf laser pointer. The buttons on all proxy lasers trigger an IR signal, which Constructable monitors using an IR receiver placed next to the camera.
Similar to the tracking button, the cut and sketch line buttons are spring-loaded in order to eliminate mode errors [13]. Users operate them without letting go of the tracking button, which users perform by rocking their finger back and forth between tracking button and the center position of tracking and cut button. For optimized ergonomics during prolonged use [13] constructable offers a dual-footswitch pedal, which is fulfilling the same purpose as the cut and sketch line barrel buttons.
Conclusion
In this paper, we proposed interactive construction as a way to enable users to interactively create functional mechanical devices. Our prototype called constructable serves as a drafting table that produces physical output in every step. By building constraints into tools, providing sketch lines and by using the laser cutter itself for high precision output, constructable offers the necessary precision required to produce simple, yet functional mechanics that cannot be created with traditional interactive fabrication tools. Equally important, constructable allows for fast fabrication by making a high-power cutting laser accessible to the user via safe low-power proxy lasers. As future work, we plan to extend constructable to allow for collaborative use.
Demos at CHI'13 and TEI'13
Packing at Hasso Plattner Institute, Berlin, Germany
Unpacking in Barcelona
Demo Setup
Demo


|
Figure 1
|
Projected climate model mean (37 models), Arctic mean (70–90 ... |
|
Figure 2
|
Projected Arctic mean (70–90°N) and annual mean changes in r ... |
|
Figure 3
|
Projected Arctic rainfall changes attributed to changes in l ... |
|
Figure 4
|
Seasonal variation in warming-induced rainfall increase (top ... |


|
Groovy Documentation | |||||||
| FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | PROPERTY | CONSTR | METHOD | DETAIL: FIELD | PROPERTY | CONSTR | METHOD |
java.lang.Object grails-app.controllers.ReportEditorMain.ArticleEditor.ArticleController
class ArticleController
Controller for creating, editing, updating and deleting Articles
| Property Summary | |
|---|---|
def |
actionSelect
Executes actions for one or more indicators |
def |
addTag
Add Tag for an article @author="Christian Wenke" |
def |
addTags
Add multiple Tags for an article @author="Christian Wenke" |
static def |
allowedMethods
|
def |
approve
sets status of an article to "approved" if the article was publish before |
def |
articleService
|
def |
autocomplete
autoComplete for article. |
def |
cancel
Action exit, cancel action, redirect to list |
def |
close
sets status of an article to "closed" |
def |
copy
Copies an Article |
def |
create
Create a new Article belonging to one specific Report |
def |
display
Show Contents of one Article belonging to one specific Report. |
def |
edit
Edit one Article belonging to one specific Report |
def |
findByTag
Find articles by tag @author="Christian Wenke" |
def |
html
Returns a html of the identified Article Note: Only for testing (xm/html) |
def |
index
|
def |
list
Shows a List of all Articles belonging to one specific Report (params.report) and filtered by a searchword and other filter-properties |
def |
mediaService
|
def |
open
sets status of an article to "development" if the article was closed before |
def |
pdf
Shows an article as PDF |
def |
pdfExportService
|
def |
pdfPreview
Generates and shows a Preview of an Article as PDF |
def |
preview
shows a preview of the edited article |
def |
removeFromView
removes the specified media from the specified view @author: Olaf |
def |
reportService
|
def |
revision
This method is called, when a user loads a revision from the edit-article function |
def |
save
Save one Article belonging to one specific Report after creating |
def |
searchArticle
Search Article |
def |
searchFilter
controller for searchable plugin |
def |
show
Show all Informations to one Article |
def |
starsrated
Shows rated stars for a specific article |
def |
update
Update one Article belonging to one specific Report |
def |
xml
Returns a xml of the identified Article Note: The xml is limited to the most important fields to generate a pdf |
| Constructor Summary | |
ArticleController()
|
| Method Summary |
|---|
| Methods inherited from class java.lang.Object | |
|---|---|
| java.lang.Object#wait(long), java.lang.Object#wait(), java.lang.Object#wait(long, int), java.lang.Object#equals(java.lang.Object), java.lang.Object#toString(), java.lang.Object#hashCode(), java.lang.Object#getClass(), java.lang.Object#notify(), java.lang.Object#notifyAll() |
| Property Detail |
|---|
def actionSelect
def addTag
def addTags
static def allowedMethods
def approve
def articleService
def autocomplete
def cancel
def close
def copy
def create
def display
def edit
def findByTag
def html
def index
def list
def mediaService
def open
def pdf
def pdfExportService
def pdfPreview
def preview
def removeFromView
def reportService
def revision
def save
def searchArticle
def searchFilter
def show
def starsrated
def update
def xml
| Constructor Detail |
|---|
ArticleController()
Groovy Documentation


|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object de.myfoo.commonj.util.AbstractManager de.myfoo.commonj.timers.FooTimerManager
public final class FooTimerManager
Implementation of the TimerManager. Each of the TimerManager schedule methods returns a Timer object. The returned Timer can then be queried and/or canceled. Applications are required to implement the TimerListener interface and may optionally implement one or both of the CancelTimerListener and StopTimerListener interfaces.
All Timers execute in the same JVM as the thread that created the Timer and are transient. If the JVM fails then all Timers will be lost.
Recurring timers will execute their TimerListener multiple times. Invocations of the TimerListener are executed serially. That is, if a timer is scheduled to repeat every 5 seconds and a previous execution is still running, then the subsequent execution is delayed until the currently running execution completes.
A TimerListener scheduled multiple times, resulting in the return of multiple Timer instances, may execute concurrently depending on implementation. Proper thread safety techniques need to be employed.
Two types of repeating timers are available:
If a fixed-rate execution is delayed for any reason (such as garbage collection, suspension, or other background activity), the late TimerListener will execute one time immediately, and then again at the next scheduled fixed-rate time.
For example, if a fixed-rate timer was to execute every hour on the hour and missed 5 executions because the TimerManager was suspended for over 5 hours, when the TimerManager is resumed, the TimerListener will run once immediately, and each execution thereafter will be on the hour.
If a fixed-delay execution is delayed for any reason (such as garbage collection, suspension, or other background activity), subsequent executions will be delayed as well. In the long run, the frequency of execution will generally be slightly lower than the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).
TimerManager
| Field Summary |
|---|
| Fields inherited from class de.myfoo.commonj.util.AbstractManager |
|---|
pool |
| Fields inherited from interface commonj.timers.TimerManager |
|---|
IMMEDIATE, INDEFINITE |
| Constructor Summary | |
|---|---|
FooTimerManager(ThreadPool pool)
Create a new TimerManager. |
| Method Summary | |
|---|---|
protected void |
finalize()
Clean up. |
boolean |
isStopped()
Returns true if all TimerListeners have completed
following stop. |
boolean |
isStopping()
Returns true if this TimerManager is stopping or has
been stopped. |
boolean |
isSuspended()
Returns true if this TimerManager is in the process
of or has completed suspending. |
boolean |
isSuspending()
Returns true if this TimerManager is in the process
of or has completed suspending. |
void |
resume()
Resume the TimerManager. |
void |
run()
run method for the timer thread. |
commonj.timers.Timer |
schedule(commonj.timers.TimerListener listener,
java.util.Date time)
Schedules a OneShotTimer to execute at a specified time. |
commonj.timers.Timer |
schedule(commonj.timers.TimerListener listener,
java.util.Date firstTime,
long period)
Schedules a TimerListener to execute repeatedly using fixed-delay execution after the firstTime elapses. |
commonj.timers.Timer |
schedule(commonj.timers.TimerListener listener,
long delay)
Schedules a TimerListener to execute once after the specified delay. |
commonj.timers.Timer |
schedule(commonj.timers.TimerListener listener,
long delay,
long period)
Schedules a TimerListener to execute repeatedly using fixed-delay execution after the specified delay. |
commonj.timers.Timer |
scheduleAtFixedRate(commonj.timers.TimerListener listener,
java.util.Date firstTime,
long period)
Schedules a TimerListener to execute repeatedly using fixed-rate execution after the firstTime elapses. |
commonj.timers.Timer |
scheduleAtFixedRate(commonj.timers.TimerListener listener,
long delay,
long period)
Schedules a TimerListener to execute repeatedly using fixed-rate execution after the specified delay. |
void |
shutdown()
Stop all timers and shutdown the thread pool. |
void |
stop()
Destroy the TimerManager. |
void |
suspend()
Suspend the TimerManager. |
boolean |
waitForStop(long timeoutMs)
Blocks until all TimerListeners have completed execution after a stop request, or the timeout occurs, or the current thread is interrupted, whichever happens first. |
boolean |
waitForSuspend(long timeoutMs)
Blocks until all TimerListeners have completed execution after a suspend request, or the timeout occurs, or the current thread is interrupted, whichever happens first. |
| Methods inherited from class de.myfoo.commonj.util.AbstractManager |
|---|
forceShutdown |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Constructor Detail |
|---|
public FooTimerManager(ThreadPool pool)
pool
- thread pool to execute timers in| Method Detail |
|---|
public void shutdown()
shutdown
in class AbstractManager
protected void finalize() throws java.lang.Throwable
finalize
in class java.lang.Object
java.lang.Throwable
public void run()
run
in interface java.lang.Runnable
Runnable.run()
public boolean isStopped()
true
if all TimerListeners have completed
following stop.
isStopped
in interface commonj.timers.TimerManager
true
if all TimerListeners have completed
following stopTimerManager.isStopped()
public boolean isStopping()
true
if this TimerManager is stopping or has
been stopped.
isStopping
in interface commonj.timers.TimerManager
true
if this TimerManager is stopping or has
been stoppedTimerManager.isStopping()
public boolean isSuspended() throws java.lang.IllegalStateException
true
if this TimerManager is in the process
of or has completed suspending.
isSuspended
in interface commonj.timers.TimerManager
true
if this TimerManager has been suspended
java.lang.IllegalStateException
- if this TimerManager has been stopped.TimerManager.isSuspended()
public boolean isSuspending() throws java.lang.IllegalStateException
true
if this TimerManager is in the process
of or has completed suspending.
isSuspending
in interface commonj.timers.TimerManager
true
if this TimerManager has been suspended
java.lang.IllegalStateException
- if this TimerManager has been stopped.TimerManager.isSuspending()
public void resume() throws java.lang.IllegalStateException
resume
in interface commonj.timers.TimerManager
java.lang.IllegalStateException
- if this TimerManager has been stopped.TimerManager.resume()
public commonj.timers.Timer schedule(commonj.timers.TimerListener listener, java.util.Date time) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
schedule
in interface commonj.timers.TimerManager
listener
- the TimerListener implementation to invoke when the timer expires.time
- the time at which the timer will expire.
java.lang.IllegalArgumentException
- thrown when the listener or firstTime is null
java.lang.IllegalStateException
- thrown when the TimerManager has been stopped.TimerManager.schedule(commonj.timers.TimerListener, java.util.Date)
,
OneShotTimer
public commonj.timers.Timer schedule(commonj.timers.TimerListener listener, long delay) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
schedule
in interface commonj.timers.TimerManager
listener
- the TimerListener implementation to invoke when the Timer expires.delay
- the number of milliseconds to wait before the Timer expires.
java.lang.IllegalArgumentException
- thrown when the listener is null or the delay is negative.
java.lang.IllegalStateException
- thrown when the TimerManager has been stopped.TimerManager.schedule(commonj.timers.TimerListener, long)
public commonj.timers.Timer schedule(commonj.timers.TimerListener listener, java.util.Date firstTime, long period) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
firstTime
elapses.
TimerListeners are executed at a constant delay based on the actual execution time. Each subsequent execution time is based off of the period and the end time of the previous execution. The period is the delay in between TimerListener executions.
schedule
in interface commonj.timers.TimerManager
listener
- the TimerListener implementation to invoke when the Timer expires.firstTime
- the time at which the first TimerListener will execute.period
- the number of milliseconds between repeating expiration intervals.
java.lang.IllegalArgumentException
- thrown when the listener or firstTime is null or the period is negative.
java.lang.IllegalStateException
- thrown when the TimerManager has been stopped.TimerManager.schedule(commonj.timers.TimerListener, java.util.Date, long)
public commonj.timers.Timer schedule(commonj.timers.TimerListener listener, long delay, long period) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
TimerListeners are executed at a constant delay based on the actual execution time. Each subsequent execution time is based off of the period and the end time of the previous execution. The period is the delay in between TimerListener executions.
schedule
in interface commonj.timers.TimerManager
listener
- the TimerListener implementation to invoke when the Timer expires.delay
- the number of milliseconds to wait before the first Timer expires.period
- the number of milliseconds between repeating expiration intervals.
java.lang.IllegalArgumentException
- thrown when the listener is null or the period or delay is negative.
java.lang.IllegalStateException
- thrown when the TimerManager has been stopped.TimerManager.schedule(commonj.timers.TimerListener, long, long)
public commonj.timers.Timer scheduleAtFixedRate(commonj.timers.TimerListener listener, java.util.Date firstTime, long period) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
firstTime
elapses.
TimerListeners are executed at a constant rate based on the initial scheduled execution time. Each subsequent execution time is based off of the period and the first execution time. This is appropriate for recurring activities that are sensitive to absolute time, such as ringing a chime every hour on the hour. It is also appropriate for recurring activities where the total time to perform a fixed number of executions is important, such as a countdown timer that ticks once every second for ten seconds.
scheduleAtFixedRate
in interface commonj.timers.TimerManager
listener
- the TimerListener implementation to invoke when the Timer expires.firstTime
- the time at which the first timer will execute.period
- the number of milliseconds between repeating expiration intervals.
java.lang.IllegalArgumentException
- thrown when the listener or firstTime is null or the period is negative.
java.lang.IllegalStateException
- thrown when the TimerManager has been stopped.TimerManager.scheduleAtFixedRate(commonj.timers.TimerListener, java.util.Date, long)
public commonj.timers.Timer scheduleAtFixedRate(commonj.timers.TimerListener listener, long delay, long period) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException
TimerListeners are executed at a constant rate based on the initial scheduled execution time. Each subsequent execution time is based off of the period and the first execution time. This is appropriate for recurring activities that are sensitive to absolute time, such as ringing a chime every hour on the hour. It is also appropriate for recurring activities where the total time to perform a fixed number of executions is important, such as a countdown timer that ticks once every second for ten seconds.
scheduleAtFixedRate
in interface commonj.timers.TimerManager
listener
- the TimerListener implementation to invoke when the Timer expires.delay
- the number of milliseconds to wait before the first Timer expires.period
- the number of milliseconds between repeating expiration intervals.
java.lang.IllegalArgumentException
- thrown when the listener is null or the period or delay is negative.
java.lang.IllegalStateException
- thrown when the TimerManager has been stopped.TimerManager.scheduleAtFixedRate(commonj.timers.TimerListener, long, long)
public void stop() throws java.lang.IllegalStateException
StopTimerListener.stopTimer
events will be
called serially with any TimerListener.timerExpired
methods. They will not execute concurrently. If a TimerListener
is executing, the stopTimer
method will be called after the
timerExpired
method has completed.
CancelTimerListener.timerCancel
events do not execute
as a result of this method.
Once the a timer manager has been stopped, it can never be re-started. Attempts to schedule a TimerListener, and resume or suspend the TimerManager will result in a thrown IllegalStateException.
stop
in interface commonj.timers.TimerManager
java.lang.IllegalStateException
- If this TimerManager was already stopped.TimerManager.stop()
public void suspend()
Execution of listeners for timers that expire while the TimerManager is suspended is deferred until the TimerManager is resumed.
This method will return immediately. Use the
TimerManager.isSuspended()
and TimerManager.waitForSuspend(long)
methods to determine the state of the suspend.
suspend
in interface commonj.timers.TimerManager
java.lang.IllegalStateException
- if this TimerManager has been stopped.TimerManager.suspend()
public boolean waitForStop(long timeoutMs) throws java.lang.InterruptedException, java.lang.IllegalArgumentException
waitForStop
in interface commonj.timers.TimerManager
timeoutMs
- the maximum time to wait
true
if this TimerManager stopped and false
if the timeout elapsed before the stop completed
java.lang.InterruptedException
- if interrupted while waiting
java.lang.IllegalArgumentException
- thrown if the timeoutMs is negative.TimerManager.waitForStop(long)
public boolean waitForSuspend(long timeoutMs) throws java.lang.InterruptedException, java.lang.IllegalStateException, java.lang.IllegalArgumentException
waitForSuspend
in interface commonj.timers.TimerManager
timeoutMs
- the maximum time to wait
true
if this TimerManager suspended and false
if the timeout elapsed before the suspend completed
java.lang.InterruptedException
- if interrupted while waiting
java.lang.IllegalStateException
- if this TimerManager has been stopped.
java.lang.IllegalArgumentException
- thrown if the timeoutMs is negative.TimerManager.waitForSuspend(long)
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


fieldName - the name of a field in the specified database file.
The field name must be in the form tablename::fieldname to specify a field that exists in a table different from the current table.
FieldComment("Customers"; "Phone Number") returns
“Customer's home telephone number” if it was entered as a comment for the Phone Number field.
FieldComment("Customers"; "Accounts::Current Balance") returns
“Customer's current balance” if it was entered as a comment for the Current Balance field in the Accounts table.


Bournemouth must face up to relegation battle, says Howe
LONDON, Dec 9 — Bournemouth have to accept they are battling to avoid relegation but are unlikely to be in a position to freshen up the squad in January despite an injury crisis at the club, manager Eddie Howe has said.
Bournemouth are 15th in the Premier League on 16 points, one point above the drop zone, following Saturday’s 3-0 defeat by leaders Liverpool.
“We’re in a relegation battle now,” Howe told British media after watching his team slump to their fifth defeat in a row.
“I think you’ve got to be realistic ...
Defender Nathan Ake and striker Callum Wilson were both injured on Saturday, taking Bournemouth’s total number of injured players to nine but Howe said the club would find it hard to bring in reinforcements.
“I think the difficulty with January — there’s a combination of things,” he said. “The money that players would cost, the quality of players you can attract is very difficult.
“If we can find something there that may be a bonus, but I think we have to focus on the players we have.”
Bournemouth next face fourth-placed Chelsea in the league on Saturday. — Reuters


For any positive integer n, the nth weak Goodstein sequence {g1, g2, g3, ...} is defined as:
For example, the 6th weak Goodstein sequence is {6, 11, 17, 25, ...}:
It can be shown that every weak Goodstein sequence terminates.
Let G(n) be the number of nonzero elements in the nth weak Goodstein sequence.
It can be verified that G(2) = 3, G(4) = 21 and G(6) = 381.
It can also be verified that ΣG(n) = 2517 for 1 n 8.
Find the last 9 digits of ΣG(n) for 1 n 16.


A place where the ancient and the modern collide, creating a unique opportunity to enjoy history in a bustling city. With approximately 22 million residents, Cairo is one of the biggest cities found in the Middle East, you can expect crowds, traffic, and noise along with the incredible chance to explore a fascinating area. Cairo keeps all five senses busy with the mix of nightlife, culture, history, and more.
The City of the Thousand Minarets is the place to go when you want to see mosques in a medieval Islamic city, palaces from the 19th century, the Giza district with the pyramids of Giza fairly close by, and Umm ad-Dunya, the Mother of the World. If you have never seen one of the Seven Wonders of the Ancient World, make sure to see the Giza pyramids and the Sphinx. Visit the Egyptian Museum to see the best collection of Egyptian artifacts around. Make sure to stop off at the souk to bargain for your purchases at the Khan el-Khalili bazaar where you can find spices, perfumes, handcrafts, jewelry and much more. Take a felucca ride or a public boat to explore the River Nile when you visit Midan Tahrir, the downtown area referred to as “Paris on the Nile”. The Pharonic Village is a great way to see how the ancient Egyptians lived and conducted their daily lives
Places to vist in egypt & main attractions to vist
- The Giza Pyramids
- Khan el-Khalili
- Egyptian Museum
- The Citadel
Here the
Egypt package includes all modes of transport i.e.,
- Air :
The basic price for air ways which includes first class and economic class 4000$ usd.
- Train :
The price for train is 2500$ usd.
- Bus :
The price for bus ways is 2000$ usd.


Analysis - Identifying Deviation of Plate Approach
It didn’t look like the typical Ben Revere at bat. In the top of the ninth in Game 6 of the ALCS, the Blue Jays trailing by 1, Revere came to the plate with runners on second and third and one out. The Kansas City Royals trusted Wade Davis to close out the series; the Jays at the very least needed Revere to get on base. The team’s MVP, Josh Donaldson, stood in the on deck circle.
Revere doesn’t hit walk off home runs, but he puts the bat on the ball more often than not - 52 swinging strikes to 372 swings with contact (reference). And yet, with a nasty curveball, Davis sent Revere walking back to the dugout. Donaldson grounded out moments later and the Royals won the pennant.
Wade Davis was the hero of the ninth inning but are there any indicators that the outs made could be attributed to Jays’ plate approach? What happened to Ben Revere?
Before analyzing the data, let's walk through the dashboard and explain what the visualizations are showing. On the left hand side, there is trending data for the player's plate approach score. Each player's pane has a grey strip with a dark grey line down the middle. This dark thin line represents the mean score. The light grey area represents where fifty percent of the data points fall. The score is optimizing towards line drives (more on this in the following sections). Some other important notes to the trend line:
- if trending above the mean, it represents a good approach to hitting line drives (or being "locked in")
- if trending below the mean, it could possibly represent a different hitting approach or possible struggles
- if a player is focusing on hitting line drives, the trend line should be tight to the grey area when successful
To the right and below the filters, there is a box plot showing the same data as a snapshot for the period. The whiskers represent the lower and upper quartiles. This view allows us to compare player profiles. Notice that Ben Revere has a higher mean score (17.7) than Dioner Navarro (14.4) and Josh Donaldson (9.4). This doesn't indicate that Revere is a better hitter, but that he profiles as a line drive hitter more often (and for which he does get accredited, see https://en.wikipedia.org/wiki/Ben_Revere#Offense). More information on how the score is calculated will be discussed in following sections.
Taking a look at the dashboard Revere starts to negatively deviate from his profile during the playoffs. Starting October 3rd against Chris Archer, he drops to the lower quartile and never recovers. At his last sample taken, October 23rd against Yordano Ventura, his score is -88.3. This is 106 points away from his mean.
A player's success or slump doesn't hinge on his plate approach score. Revere started with Toronto going 0 for 13, yet his plate approach score indicates that he was still hovering close to his normal. From Aug. 21st to 29th, he had an 8-game hitting streak which bumped is batting average significantly, yet his plate approach score indicates that he was no more locked in than when he first joined the team. It was not until the playoffs that his plate approach score took a dive. The weekly line drive count for his last month in baseball for 2015 is 10, 7, 0, and 2 (reference).
The dashboard indicates that Revere was struggling with his plate approach come the Kansas City series. This intelligence could be used to go back to see what he was doing in his at bats prior to October 3rd when he was more "locked in". Maybe Revere could have hit one more line drive when the team needed it most.
Abstract
Offensive production rates are prone to rise and fall during hot streaks and slumps. It can be difficult to determine whether these periods are due to the quality of plate approach or some other factor. For instance, a batter's average may drop over a period due to quality pitching despite maintaining a good approach. In contrast, a batter may be maintaining his good offense through some seeing-eye singles. The following analysis and methodology will focus on uncoupling some of these other factors. The goal is to have a metric that can gauge whether a batter is trending away from their mean approach. Also, it provides a clear visual indicating when a batter starts to deviate.
The following few sections explain how to arrive at a measure for Plate Approach. If you would like to start playing with the Dashboard to see what it looks like and then jump back click here or use the PAoLD (Plate Approach Optimized to Line Drives) Dashboard link on the header ribbon.
Selecting Controlled Samples
Let's define a sample as a pitcher going through the batting order. This should give us roughly 2 to 3 sample sets of data per game per team to use for analysis. Note that these samples will be against starting pitchers and long relievers. In this way, we can control factors such as:
- pitcher's fatigue level - each sample is limited to roughly 40 to 50 pitches
- environmental factors - each sample is on the same day/night under the same weather conditions
- home plate umpire
- manager's playing matchups
Defining Plate Approach (Optimized to Line Drives) - PAoLD
Let's start with a simple premise: each time a batter swings his intention is to put the ball in play. (There is the exception where a batter may be spoiling a pitch, but let's keep definitions simple for working towards a minimum viable product.) Counting the number of swings to an event gives us a measure (the fewer swings taken to reach the event is preferred). To go one step further, I decided to track the number of swings to a line drive. As a first stake in the ground, this seems like a good proxy for a quality hit. It would be interesting to perhaps pull in hard contact data or blend different plate approaches ("swings to fly ball", "swings to ground ball", etc.), but I leave this as a future version feature.
Next, we only consider our controlled samples when we count the swings to a line drive. Once a line drive is hit (within a controlled sample), then we can reset and start from zero.
Now, we have sample sets (with nine players in each of them) with how many swings they have taken until they last hit a line drive. Let's transform those numbers into a score by finding the mean and calculating their standard deviation from the mean (see how this was derived from the dimensional model). Since I used a normal distribution, 99.7% of the data is within 3 standard deviations. To convert the number to look more like a score, I divided the number by 3 and multiplied by 100. Then, I inversed the trend line by multiplying by -1 so visually we can see an upward trend as positive when we start to look at the Dashboard. To summarize, controlled samples were created to compare the batter's ability to produce a line drive in the fewest number of swings. The sample assumes everyone is trying to put the ball in play and that line drives will serve as proxy to a quality hit.
Dashboard (How To Use)
Data for all the Hackathon judges' teams have been included. Most likely, the starting state of the dashboard will show too many players to observe insight. To filter down data:
- Use the "Date" range filter in the top-right corner
- Enter in a player's team into the "Batter" filter underneath the Date filter
- "COL*" for Colorado Rockies
- "CLE*" for Cleveland Indians
- "DET*" for Detroit Tigers
- "MIL*" for Milwaukee Brewers
- "MIN*" for Minnesota Twins
- "NYM*" for New York Mets
- "PIT*" for Pittsburgh Pirates
- "TOR*" for Toronto Blue Jays
- Also, partial player names may be entered (ex. "Cutch" for Andrew McCutchen)
Dashboard
Methodology
Using the data set provided by TruMedia Networks for the Hackathon, dimensional models were created as the basis for a data warehouse. Python scripts were used to ingest the data:
The first model below represents the "Pitch By Pitch" data provided:
Next, an aggregate model was created to represent "At Bats". This model defines new metrics not found in the original data set. As "swings to ball in play" and "swings to line drive" were needed for the analysis, business logic was written within the Python scripts to produce these metrics.
With sound data models in place, it made analysis much easier via SQL. For example, the query used to produce the data extract was:
SELECT CONCAT(dpb.teamAbbreviation, ' - ',dpb.playerName) AS batter, CONCAT(dpp.teamAbbreviation, ' - ',dpp.playerName) AS pitcher, dd.date, f.mlbBaselineSampleDim, (f.sampleSwingsToBallInPlay - x.avgSampleSwingsToBallInPlay)/x.stddevSampleSwingsToBallInPlay AS ssbipScore, (f.sampleSwingsToLineDrive - x.avgSampleSwingsToLineDrive)/x.stddevSampleSwingsToLineDrive AS ssldScore FROM common.Mlb_FACT_AtBat f JOIN common.DIM_Date dd ON f.dateId = dd.id JOIN common.Mlb_DIM_Player dpb ON f.mlbPlayerBatterId = dpb.id JOIN common.Mlb_DIM_Player dpp ON f.mlbPlayerPitcherId = dpp.id JOIN ( SELECT f.mlbBaselineSampleDim, AVG(f.sampleSwingsToBallInPlay) AS avgSampleSwingsToBallInPlay, STDDEV(f.sampleSwingsToBallInPlay) AS stddevSampleSwingsToBallInPlay, AVG(f.sampleSwingsToLineDrive) AS avgSampleSwingsToLineDrive, STDDEV(f.sampleSwingsToLineDrive) AS stddevSampleSwingsToLineDrive FROM common.Mlb_FACT_AtBat f WHERE f.mlbBaselineSampleDim != 0 AND f.mlbSampleDim IN ( SELECT DISTINCT f.mlbSampleDim FROM common.Mlb_FACT_PitchByPitch f JOIN common.Mlb_DIM_Player dp ON f.mlbPlayerBatterId = dp.id AND dp.teamAbbreviation IN ( 'COL', 'CLE', 'DET', 'MIL', 'MIN', 'NYM', 'PIT', 'TOR' ) ) GROUP BY f.mlbBaselineSampleDim ) x ON f.mlbBaselineSampleDim = x.mlbBaselineSampleDim ORDER BY f.mlbBaselineSampleDim;
With the data to be analyzed in hand, the last step was to develop the dashboard using a visualization tool. Tableau Pubic was leveraged to build out the Dashboard.
Reference Queries
SELECT SUM( CASE WHEN ds.pitchResult = 'SS' THEN 1 ELSE 0 END ) AS swings_misses, SUM( CASE WHEN ds.pitchResult IN ('F', 'FT', 'IP') THEN 1 ELSE 0 END ) AS swings_contact FROM common.Mlb_FACT_PitchByPitch f JOIN common.DIM_Date dd ON f.dateId = dd.id and dd.date >= '2015-08-01' JOIN common.Mlb_DIM_Player dp ON f.mlbPlayerBatterId = dp.id AND dp.playerName = 'Ben Revere' JOIN common.Mlb_DIM_Situation ds ON f.mlbSituationId = ds.id AND ds.pitchResult IN ('SS', 'F', 'FT', 'IP')
SELECT WEEK(dd.date), COUNT(*) FROM common.Mlb_FACT_PitchByPitch f JOIN common.DIM_Date dd ON f.dateId = dd.id and dd.date >= '2015-08-01' JOIN common.Mlb_DIM_Player dp ON f.mlbPlayerBatterId = dp.id AND dp.playerName = 'Ben Revere' JOIN common.Mlb_DIM_Outcome doc ON f.mlbOutcomeId = doc.id AND doc.battedBallType = 'LD' GROUP BY WEEK(dd.date);
Acknowledgements
Thanks to:
- Sean Shaughnessy for playing around with the dashboard and finding interesting results
- Aaron Hutchins for editing the Analysis piece
- Paul Luong for affirming the data models
- Ray Kwong for reading the piece from an analysts perspective and finding mistakes


nanoparticles silver AgNPs bacterial variations concentration size {border-style px;} #ffffff;} species antibacterial NPs AgNP extract using Figure growth observed effect leaf coli efficacy potential ... LEA MIC NP, different samples subtilis case concentrations plant px; synthesis zeta {font-family Arbutus MBC Silver activity font-size lower nanoparticle reducing reported tested AgNPs. Electron UV-Vis bacteria biological cell double; gram-negative infections mean nm, produced properties unedo used μg/mL AgNO Green However, Microscopy Nikolaos aeruginosa, analyzed antimicrobial bactericidal border-color border-width control diameter estimates groups high membrane membranes pathogens range similar smaller solid; values {font-style {font-weight μg/mL, (LEA) Bacterial Chatzinikolaidou DLS Dimitrios Dynamic Galdiero Growth Light Maria Michailidis Pseudomonas Transmission USA) [], action adjusted aeruginosa background bold broth characterization compared conceived containing corresponding courier; designed effects electron em; epidermidis evaluated experimental final gram-positive green higher low measured methods min nanoparticles, new prepared produce pt;} significant slightly solution stability surface synthesized test


Copy and paste the JSON from your web page to populate the fields "Label" and "URL" in this webtags dashboard. Or you can press button "Paste example" at the left bottom corner of this window.
Export JSON
Copy and paste the code below into the right place on your web page.