|
TinyOS 1.1.x Significant Changes
|
This document outlines the changes that have occured in TinyOS in the minor releases since the last major release (1.1.0). The changes are listed by release number. A change made in release 1.1.(n) is not also listed under release 1.1.(n+1).
You can view the cvs commit log for the core tree at http://mail.millennium.berkeley.edu/pipermail/tinyos-commits/. You can join the tinyos-commits mailing list at http://mail.millennium.berkeley.edu/mailman/listinfo/tinyos-commits
|
Significant Changes in TinyOS between v1.1.14 and 1.1.15
Updated Dec 28, 2005 |
Kamin Whitehouse's Hood has been moved to the core. Hood provides a Distributed Programming Abstraction for sensor networks and includes 5 new tinyos libraries to: 1) automatically define a namespace of node attributes such as location, sensor values, etc, which is exposed through a central 'registry' 2) store these attributes to flash 3) expand that namespace to attributes of neighbors (hood) 4) expose arbitrary functions, including the get/set functions of registry attributes to other nodes and/or the pc through an rpc interface 5) expose arbitrary module variables through the same rpc interface. These libraries require code generation and must be used with nesc 1.2 or later. The code generation scripts are in tinyos-1.x/tools/scripts/codeGeneration.
You can read an overview of hood and find pointers to papers at Kamin's project page. Further documentation can be found at the Hood wiki.
Drip/Drain. Gilman Tolle's Drip and Drain work has been moved from beta into the core (tinyos-1.x/lib).  Drip/Drain comes with extensive server-side java tools and test applications. You can read more about the Drip and Drain protocols in the README files in their respective beta directories: beta/Drip and beta/Drain.
pytos. Kamin Whitehouse's pytos is a python-based toolchain for tinyos with a dynamic typing system. It automatically imports the enums, types, message formats, modules, variables, and rpc functions from applications that are compiled with the 'rpc' and 'nescDecls' targets.
pytos includes several utilities such as the ParseArgs.py utility to parse the motecom and platform arguments from the commandline and Listen.py that pretty prints all incoming packets, even if they come in over a routing layer such as Drain (see below). MessageSnooper is a library that knows about all routing layers. It uses introspection to see which routing layers are compiled into the application and registers for all packet types for all routing layers.
Please see the following two wiki pages for pytos documentation: Pytos Installation Instructions and Pytos Development Environment .
Deluge has had a general code cleanup. The trickle timer period has been increased by two orders of magnitude. Rebooting to the same image is now possible. Can ping a specific node ID. Server-side java tools allow rebooting even when one or more nodes not running Deluge as expected. TOSBoot size has been reduced for the MSP platform. TOSBoot will fail if the program image starts at the wrong address (program too small or compiled for a different bootloader/revision).
Deluge now forwards messages that are not only valid deluge messages, but also do not have image numbers greater than what is supported (could occur when running nodes with different number of images) (Jonathan Hui).
Fixed a bug in msp430hardware.h:_nesc_atomic_sleep(). If timerA is used by a module (such as the ADC) for triggering samples, the DCO must stay on. If the samples are recovered by the DMA, then the timerA interrupt enable bit is not set (since the DMA handles the ifg flag being set). In this case, you want to check if timerA is NOT in "stop_mode", and if it is using a clock source that relies on the DCO. (Joe Polastre)
Fixed LED PowerState bug so that PowerState's version of the LEDs now reflects reality (Viktor Schnayder).
|
Significant Changes in TinyOS between v1.1.13 and 1.1.14
Updated July 29, 2005 |
Deluge 2.0. Version 2 of Deluge, TinyOS's state-of-the-art network programming system, has been moved from beta into the main tree and is now the default version for both AVR and MSP430 platforms. Among many significant Deluge changes, the TOSBoot bootloader is now installed by default when installing any TinyOS application. This policy is implemented by setting TINYOS_NP ?= BNP in tools/make/Makedefaults. The user can override the policy by setting TINYOS_NP=x where x is anything != to BNP. TOSBoot also provides on/off capability for telosb and tmote sky nodes by holding the user button when resetting a node. You can read in detail about Deluge 2.0 at the Deluge web site.
More sample apps.Several apps have been moved from tinyos-1.x/beta into the core apps directory tinyos-1.x/apps: GlowRadio, GlowLeds, Pong, SurgeTelos, TelosADC and TelosPWM. To support these apps, the following libraries were also moved from beta into the core: lib/Oscope, lib/LedsIntensity and lib/MultiHopLQI.
New Flash Support. New Flash support for new Flash BlockStorage interfaces have been added for the AT45DB and STM25P flash chips (found in the Mica family). Among other things, this allowed Deluge 2.0, which requires these new interfaces, to be ported to all of the Mica motes.
Several improvements to the TOSBase bridge application:
The Hamamatsu sensor has a slightly different interface in that it is no longer necessary to set the ADC pin SEL functionality; this is done automatically by MSP430ADC12M. ADCSingle and ADCMultiple interfaces have been added to the PAR and TSR sensors. Lastly, the drivers have been cleaned up. The new driver has new features not found in any previous version of the humidity sensor driver. These features include, but are not limited to:
Motelist. Motelist for Linux kernels 2.6.x now requires only the /sys filesystem such that superuser access is no longer necessary to read special files. Alos fixed motelist for procfs in kernel 2.4.x to show the correct usb path given in usbserial not usb/devices.
Bug fix to tos/platform/micaz/VoltageM.nc; state was not getting reset to S_IDLE (Razvan Musaloiu).
Fixed critical bug that would cause InternalFlash to misbehave after 128 writes. Wasn't casting a variable to int8_t before testing its sign (Jonathan Hui).
Bug fix in CC2420RadioM.nc for race condition in CC2420 radio stack: If ACK comes in before PacketSent() runs, the PacketSent() task could be posted twice (duplicate sendDone events). Fix: set the state to a different value to suppress the later task (Matt Welsh).
Fixed bug in java/net/tinyos/message/MoteIF.java where if source was started before MoteIF initialiser called, source.awaitStartup() wasn't called because of a prior exception when attempting to start source (David Gay).
The problem observed was that timers in TOSSIM sometimes fire early. This happened because of a bad interaction between how TOSSIM emulates the hardware counter and how it handles time events (David Tucker).
Bug fix in Mate VM Hamamatsu sensor implementation where the HamamatsuM.TSR was accidentally wired to the HamamatsuC.PAR rather than Hamamatsu.TSR. (Mark Kranz)
|
Significant Changes in TinyOS between v1.1.12 and 1.1.13
Updated May 25, 2005 |
New DemoSensorC component added to Mica Weatherboard sensorboard.
tos/interfaces/HPLPowerManagement interface now has enable() and disable() commands to enable proper nested usage.
Deluge: improved error-case handling in bootloader and added image verification by checking CRCs. Reduced bootloader codesize by about 1.5K; GoldenImage now compiles to 20894 bytes (in nesc-1.2alpha7). Overhead of including Deluge in SurgeTelos is 7746 bytes, which includes the storage stack.
Code cleanup for MSP430's internal flash; reduces code size by nearly 25%.
Because Deluge's StdControl.init() configures TOS_LOCAL_ADDRESS, moved MultiHop basestation initialization from StdControl.init() to StdControl.start().
Matlab documentation in tools/matlab/doc has been consolidated into a single FAQ in the same directory and updated the tutorial in doc/matlab.html.
Make system additions:
Removed some atomic sections from around commands in MSP430 platform-specific files where (1) the command compiles to a single MSP instruction and (2) it doesn't break Deluge for some unknown reason. (Recommended by Henri Dubois-Ferriere, EPFL)
Added code to help with serial problems between Linux 2.6, USB serial ports, and the MIB510. These changes included changing the port settings and adding a retry if the programmer doesn't respond initially. Also changed the COMn reference to /dev/ttySn to help Cygwin work better.(David Gay, Intel Berkeley)
Fixed a bug in CC1000ControlM.nc where the incorrect register was written. (Joe Polastre, UCB, SF Bug#1110032)
Fixed CC1000 stack to work if someone specifies a 0-length packet. (Joe Polastre, UCB)
|
Significant Changes in TinyOS between v1.1.11 and 1.1.12
Updated April 25, 2005 |
In CC2420 stack, added additional protection on starting and stopping the SPI bus. Keeps track of whether the component is busy doing something before disabling SPI. Also added more protections in other functions for enable/disable.
In preparation for TinyOS 2.0, many components are being rewritten according to TEP (TinyOS Enhancement Protocol) 101. You can read TEP 101 (currently in draft form) on the TinyOS 2.0 Working Group page. Please also refer to other TEPS on that page. Along these lines code has committed an HPL for the telos DMA and other components. Please refer to the http://mail.millennium.berkeley.edu/mailman/listinfo/tinyos-commits archives for full details.
A new Voltage Component replaced the old one in tos/system. The new component's interface returns the ADC value in millivolts, and uses new underlying platform-specific voltage modules. On the msp430 platform, the voltage module automatically switches between 1.5 and 2.5V reference voltage depending on what the measured system voltage. Allows for accurate sampling of voltages above 3V. The conversion was carefully coded to reduce computation time but does include one integer divide; those concerned about this computation time can use the ADC interface directly.
Rewrite for MSP430 DCO calibration/init methods. Single calibration/initialization gains include: order of magnitude faster (9ms), 2/3 smaller (74 ROM bytes), 5-8 bytes less RAM. Using this calibration routine, have successfully transmitted over the UART at up to 1Mbaud (though 256Kbaud appears overall more robust). Continual/sliding-mode recalibration improvements include: the DCO can be adjusted by about 0.35% every two seconds; this routine can account for a change of about 0.5 degC / sec. Please see http://mail.millennium.berkeley.edu/pipermail/tinyos-commits/2005-March/005959.html for details.
The ncc family of tools (ncc, mig, ncg, nesdoc) has moved from the nesc project's source tree into the TinyOS source tree. ncc can be found in tools/src/ncc.
tools/scripts/taskCount.pl will count the number of tasks in an application for you. For example, to count the tasks in Blink for the telos platform, do 'taskCount.pl telos'. (You must compile the application beforehand.)
Bug fixed where when stop is called on HPLCC2420M while it is in the middle of an operation then the while(spi_action) loops never return and system is hosed. By including an enable flag, the loops break out and program execution continues. (Joe Polastre, UCB)
Merged in proposed changes suggested by Anders Blomdell, who wants bsl to
recognize a mote reference number and deduce the serial port. Modified
his original submission to recognize bsl,ref, instead of bsl, to
avoid any ambiguity between serial port names and reference names. (Anders
Blomdell, Lund University, Sweden)
Tweaks to build-mspgcc to make it more robust: added some
exit code under certain conditions and modified how BUILD_BASE is
defined. (Henri Dubois-Ferriere, EPFL, Switzerland) Another tweak to
enable use within firewalls (David Gay, Intel).
Slow down broken I2C, so that the mda300ca digital I/O stuff works. This involved changing a wait in the I2C task from a nop to a TOSH_uwait(1). (David Gay, Intel)
Updated enable/disable functions or msp430 USARTs to appropriately change the pin functionality when enable or disable are called. (Jonathan Hui, UCB)
Updated February 23, 2005
Deluge. Added a script to generate an xml file for a TinyOS
image. The file includes various metadata information important for
network programming. Sample output is included below. Currently only
included when building for telosa/b. Increased the program name length
in Ident.h from 10 to 17 bytes to be more meaningful.
MSP430. In preparation for TinyOS 2.0, many MSP430 platform components are being
rewritten according to TEP (TinyOS Enhancement Protocol) 101. You can
read TEP 101 (currently in draft form) on the TinyOS
2.0 Working Group page.
MSP430ADC12[Advanved|Basic] has been replaced by
MSP430ADC12[Single|Multiple]; high-frequency sampling of above 70ksps
is now available. HIL (see TEP 101 for what HIL means)now provides
ADCSingle and ADCMultiple (to stay compatible also ADC and ADCControl
are provided). The MSP430 platform also saw the initial checkin of
hardware I2C module driver for. The I2C module the
f15x and f16x series of microcontrollers as well as any others that
have the built-in hardware I2C module. Details on the msp430 I2C interface
are
here. This MSP430 work was contributed by Jan-Hinrich Hauer, Vlado Handziski, and
Kevin Klueska of TU-Berlin.
Telos B.A more efficient CRC calculation has been added
by providing a method in the HPL. A new component, I2CPacket, was committed
which uses the new I2C functionality described above; I2CPacket is responsible
for obtaining exclusive access of the I2C bus (in the case of telosb,
it is shared with SPI and UART) starting the I2C component (MSP430I2CM
in our case), running the operation, and then stopping the I2C
component (which restores the previous settings for the USART, such as
SPI configuration for the radio). More details on I2CPacket can be found
here.
The TinyOS RPMS sets the MAKERULES environment variable to point to
the new make system in tools/make. If you want to use the old
system simply comment out where MAKERULES is defined in
the file /etc/profile.d/tinyos.sh. If MAKERULES is not defined the
old make system will be used.
New options to support Debian linux were added to motelist-linux2:
Fix for the MicaZ CC24220 where sleep mode halted and didn't wake up.
(Jaidev Prabhu, Crossbow)
Fixed a bug in the AVR makefiles which caused images to be recompiled
under the reinstall command. (Jonathan Hui, UC Berkeley)
Fixed a bug in the HPLUART1M.stop() code reported by Paul Young for the
mica2 platform.
Updated January 7, 2005
Significant Changes in TinyOS between v1.1.10 and 1.1.11
Added functionality to avr makefile for compiling frequency
into app via the make extra flags. See /tools/make/avr/freq.extra.
Significant Changes in TinyOS between v1.1.9 and 1.1.10
Additional radio configuration tweaks are available for the CC2420 radio:
1.1.10 includes full support for Berkeley's Telos Revision B. Rev B has 10kB of RAM (vs 2kB for Rev A) and 48kB of Flash (vs 60kB for Rev A), reduced radio startup time, JTAG support, and more. Moteiv has written an changes document for Rev B.
New build scripts for the MSP platform tools are now in tools/src/mspgcc. The build-mspgcc script will download, build, and install mspgcc with the appropriate patches for the newest, greatest msp430 devices.
Miscellaneous bug fixes and platform cleanup were done on the C serial forwarder [tools/src/sf]. See here, here, and here for details. (David Gay, Intel Research)
Fixed bug so that now any sensorboard will work with PowerTOSSIM. (Victor Schnayder, Harvard)
Fixed bug in which message pointers could be erroneously shared by multiple motes in TOSSIM (Matt Welsh, Harvard).|
Significant Changes in TinyOS between v1.1.8 and 1.1.9
Updated December 1, 2004 |
PowerTOSSIM, a power modeling extension to the TOSSIM TinyOS simulator, is included in 1.1.9. PowerTOSSIM accurately models power consumed by TinyOS applications. You can find more information at http://www.eecs.harvard.edu/~shnayder/ptossim/ . (Victor Schnayder, Harvard.)
Since 1.1.6, TinyOS has included an alternative make system which allows easier introduction of platforms. We have not made this make system the default, however, because it requires make 3.8 which (1) not everyone has and (2) has some bugs which are tickled by some of TInyOS's major subsystems. Towards fixing (2), Phil Levis has provided a patch for make 3.8. We have included a patched make executable in tools/make (the executable is also present in 1.1.8).
On the TI MSP430 platform, each sensor now has its own header file with constants for interface ID and the "adcPort" parameter. This makes code cleaner and saves RAM, since uniqueCount("ADCPort") now reflects the actual number of interfaces wiring to ADCC. Some files in the corresponding platforms were modified to take into account the new msp430 definitions. (Jan-Hinrich Hauer, TU Berlin.)
Bug fix to the avr and msp make rules to fix the RAM usage byte count; was previously undercounting usage. (David Gay, Intel Research)
Bug fixes to SerialForwarder multiple platform support. Details can be found at http://mail.millennium.berkeley.edu/pipermail/tinyos-commits/2004-November/005527.html. (David Gay, Intel Research)
|
Significant Changes in TinyOS between v1.1.7 and 1.1.8
Updated November 15, 2004 |
TinyOS 1.1.8 includes the new network programming system called Deluge . Deluge provides the ability to wirelessly install a new program image. This is accomplished by propagating a program image over the wireless network and having each node program themselves with the new image. See the Deluge web site for more information on how to start programming your motes wirelessly with Deluge.
Initial checkin of the InternalFlash interface. This is a generic interface for reading and storing values in the internal flash of a microcontroller. This generic interface is necessary since different platforms have different requirements when writing values to internal flash. For example, on the msp the entire segment which encloses the intended write location must first be erased. Some software logic is required to make sure all other values not at the intended write location are preserved. However, on the avr platform (which has an EEPROM), an erase of an entire segment is not required.
Replaced the CC2420 stack with new interrupt-driven stack. New interfaces (Capture and Interrupt) signal radio interrupts on a platform independent basis and allow time stamping information to propogate up through the radio stack. This interrupt driven radio stack is needed to support time stamping as well as low power listening.
Introduced a Quick/Fast CRC calculation for MSP430 based platforms. See tos/platform/msp430/crc.h.
The tools/make makefile system now has support for Telos Rev B (telosb vs telosa).
Matt Welsh has added some support for the FreeBSD development platform.
1.1.8 includes many bug fixes in the
Patch submitted by David Moore to fix a condition under which the CC1000 stack hangs due to a task queue starvation problem. Details can be found at http://mail.millennium.berkeley.edu/pipermail/tinyos-commits/2004-August/004891.html. The fix was to only make some relatively expensive calls if a post succeeded rather than whether or not the post succeeded; not making those calls gives the task queue enough time to run in the case that the post failed due to task queue overflow.
Bug reported by Thanos Stathopoulos which occured in CC1000 stack when acks were enabled and broadcast messages were sent. This fix causes the radio to only wait for an ack if the message is unicast, otherwise it transitions to the TX_DONE state. Details are at http://mail.millennium.berkeley.edu/pipermail/tinyos-commits/2004-August/004990.html.
This patch fixes two sources of Timer error. The first is when a task post fails: TimerM now sets state appropriately and does not blindly assume it was able to fire its timers. The second is when adjusting the firing interval in very small amounts. In the old version, a subtle race condition could cause TimerM to set the compare register to a past value. Instead of firing in 1ms, it would fire in 256 ms, which completely threw all timers off.
For full details on this patch, refer to the discussion on the tinyos-devel list under the threads "mica* TimerM" and "TimerM.nc changes" on Aug. 9-12 2004.
Bug fix from Hardy Griech in tos/lib/MultiHopLQI: update interval should have been in seconds, not milliseconds.
Bug fix by Crossbow on micaz platform where TIMER2 Compare Interrupt Service routine incorrectly sets TIMER0 (should be TIMER2) scale and interval when in REPEAT mode.
Bug pointed out by Peter Tian in CC1000ControlM: removed outp() statement to timer3 (not needed, adverse affects when others are using timer3).
Bug fix submitted for tos/platform/telos/TimerJiffyAsyncM.nc by phil buonadonna for timers longer than 0xFFFF that caused an overflow-ish problem.
Bug fix from Xiaofan Jiang, Joe Polastre for tos/platform/msp430/ADCM.nc: reset busy-variable in dataReadySingle so that the eventhandler can call getData right away.
Added motelist support for linux. Motelist lists currently connected telos motes and which USB port they're connected with.
Since 1.1.7 but before 1.1.8, Phil Levis released version 2.0 of Maté. Maté allows you to program sensor networks with high-level scripts that compile down to bytecodes for an application specific virtual machine. RPMs and a full set of tutorials can be found at http://www.cs.berkeley.edu/~pal/mate-web/ .
Index >|
Significant Changes in TinyOS between v1.1.6 and 1.1.7
Updated July 14, 2004 |
1.1.7 includes platform support for MicaZ and Telos . For more information on the MicaZ platform, please see Crossbow. For more information on Telos, please see Moteiv . The telos support includes code contributed by TU-Berlin for the TI MSP430.
TASK-TinyDB 1.1.3 will be released in conjunction with tinyos-1.1.7. TASK-TinyDB 1.1.3 includes fixes to address compilation errors caused by changes in TinyOS 1.1.6 and 1.1.7.
Index >|
Significant Changes in TinyOS between v1.1.5 and 1.1.6
Updated May 10, 2004 |
TOSSIM now supports the PageEEPROM component for the PC platform.
There is a new make system which, among other things, eases the addition of new targets and platforms. The old make system is still the default. To read about and use the new make system, see tinyos-1.x/tools/make/README.
You can now have >= 16 timers thanks to a bugfix in tos/system/TimerM.nc.
Add hardware platform abstraction component for Mic component to fix the cross-platform interrupt issues. TONE_INTR compiling issue is also resolved.
A number of changes to the simulation tools. Please see the tinyos-1.x/ChangeLog for details.
MACControl interface change. MacControl no longer has the Backoff events in it. It seemed that people really just wanted to turn ACKs on and off and likewise other radio functionality but not worry about changing the backoff. As a result, there are two interfaces--MacControl and MacBackoff and you can wire to the appropriate one. The CC2420 radio stack also has these two interfaces.
Task scheduling. You can now change the size of the task queue by adding -DTOSH_MAX_TASKS_LOG2=n (to get 2^n tasks) to the compile command line via, say, a Makelocal file.
Tinyos-contrib version 1.1.2 was released a few weeks ago. It includes the first release of TinyGALs. The tinyos-contrib rpms can be found in the linux and windows rpm directories along with all of the other 1.1.x releases.
Index >|
Significant Changes in TinyOS between v1.1.4 and 1.1.5
Updated 26 March 2004 |
This section outlines the changes that have occured in TinyOS since the 1.1.4 snapshot release and the 1.1.5 minor release. While there are no major changes for 1.1.5, the changes with the most impact include bug fixes and improvements to the Tython scripting environment, an update release of TinyDB/TASK, plus miscellaneous bug fixes across the system.
Improvements and bug fixes were make to Tython, the TOSSIM scripting environment introduced in 1.1.3. The improvements made include internal restructuring to support the simulation of SimObjects that are not MoteSimObjects (this may cause minor incompatibilities with plugins)and some miscellaneous bugs that left the TOSSIM processes running after TinyViz/Tython exited.
For more information about Tython, please see the User Manual in the doc/tython directory.Among numerous tweaks: fixed bug #909637 regarding interrupt pin incompatability between the MICA and the MICA2; fixed the file save operation in the Oscilloscope Java GUI to correctly handle dropped packets and null elements in the vector.
The 1.1.2 minor release of TinyDB/TASK is expected to be released simultaneously with TinyOS 1.1.5. The 1.1.2 TinyDB/TASK snapshot will include numerous bug fixes and upgrades. For more information on TinyDB, please see documentation in the doc/ directory. We will also be releasing some contrib directories where the authors have requested it.
Index >|
Significant Changes in TinyOS between v1.1.3 and 1.1.4
Updated 5 February 2004 |
This section outlines the changes that have occured in TinyOS since the 1.1.3 snapshot release and 1.1.4 minor release. The major changes in 1.1.4 include the new tython scripting environment plus various bug fixes.
TinyOS 1.1.3 includes Tython. Tython is a TOSSIM scripting environment that uses a Java implementation of the Python programming language. Tython allows users to write scripts to do things such as dynamically move motes, inject packets, and inspect the internal state of the simulation. Tython allows full access to the existing Java TinyOS toolchain, so users can write a piece of TinyOS messaging code, generate a Java packet object from it using mig, then use Tython to inject those packets into a running simulation.
Tython is integrated with the TinyViz environment; this means that, for example, if a script makes a mote move, a user can see the movement in the TinyViz visualization and its radio connectivity will be updated as expected. TinyViz and Tython can be run separately from one another.
For more information about Tython, please see the User Manual in the doc/tython directory.
The 1.1.2 minor release of task-tinydb is expected to be released simultaneously with TinyOS 1.1.4. The 1.1.2 task-tinydb snapshot will include numerous bug fixes and upgrades. For more information on TinyDB, please see documentation in the doc/ directory.
Index >|
Significant Changes in TinyOS between v1.1.1 and 1.1.3
Updated 7 January 2004 |
This section outlines the changes that have occured in TinyOS since the 1.1.1 snapshot release and the 1.1.3 minor release. The major changes in 1.1.3 include the new MAC layer, B-MAC, as well as various bug fixes.
TinyOS 1.1.3 includes B-MAC, a new MAC layer w/ CSMA with collision avoidance, gain control, channel filtering for channel clear decisions; max bw from 42 pckts/sec to 53 pckts/sec, outperforms the 1.1 MAC layer by over 100% (in terms of packet throughput) while achieving 85% channel utilization.
Released simultaneously with TinyDB 1.1.3 is the 1.1.3 minor release of task-tinydb which includes numerous bug fixes and upgrades. For more information on TinyDB, please see documentation in the doc/ directory.
Index >|
Significant Changes in TinyOS between v1.1.0 and 1.1.1
Updated 24 November 2003 |
This section outlines the changes that have occured in TinyOS since the last major release (1.1.0) and the 1.1.1 minor release. The changes in 1.1.1 include a more reliable routing implementation, a calibrated interface to the ADC as well as various bug fixes.
TinyOS 1.1.1 includes a new routing module, named MintRoute with increased reliability. The algorithm features improved parent selection leading to relatively shorter trees.
A new ADC interface allows for calibrated and non-calibrated (legacy) ADC reads by providing two additional methods to control reference value calibration. The new interface is used by default, but supports legacy ADC reads. See the ADCControl.nc file for more information.
The TinySec usage model has changed. Rather than having to wire to
SecureGenericComm to use TinySec, you can now leave your wiring files the same
and simply use TINYSEC=true on the command line. Example:
make mica2 TINYSEC=true
This works with any application using the Makerules in the apps
directory. The methods for changing the security mechanism used
(authentication, authentication+encryption, or CRC) for transmission
still use the TinySecMode interface exported by TinySecC, but will likely
change in the next release.
There is now a reset target in Makerules: make platform reset.
Bug fixes include I2C bug fixes, and a compile fix for tossim so that newer versions of cygwin (newer than that distributed with TinyOS 1.1.0) work.
Released simultaneously with TinyDB 1.1.1 is the 1.1.1 minor release of task-tinydb which includes numerous bug fixes and upgrades. For more information on TinyDB, please see documentation in the doc/ directory.
Index >


Data in custom formats can be shared with target applications that support them. In this example, we share data about a book in JSON microdata format. A supported target app, such as the Share Target sample, must be installed in order to have a place to send the data.
Data Package Title:
Data Package Description:
Custom Data Format Id:
Custom Data Format Value:
To share, bring up the charms bar and select Share (or press Win+H).
You can also invoke the share window programmatically after prompting the user in response to an event
(e.g. "You just beat the high score. Do you want to share this with your friends?")


In this notebook, some template code has already been provided for you, and you will need to implement additional functionality to successfully complete this project. You will not need to modify the included code beyond what is requested. Sections that begin with '(IMPLEMENTATION)' in the header indicate that the following block of code will require additional functionality which you must provide. Instructions will be provided for each section, and the specifics of the implementation are marked in the code block with a 'TODO' statement. Please be sure to read the instructions carefully!
Note: Once you have completed all of the code implementations, you need to finalize your work by exporting the iPython Notebook as an HTML document. Before exporting the notebook to html, all of the code cells need to have been run so that reviewers can see the final implementation and output. You can then export the notebook by using the menu above and navigating to \n", "File -> Download as -> HTML (.html). Include the finished document along with this notebook as your submission.
In addition to implementing code, there will be questions that you must answer which relate to the project and your implementation. Each section where you will answer a question is preceded by a 'Question X' header. Carefully read each question and provide thorough answers in the following text boxes that begin with 'Answer:'. Your project submission will be evaluated based on your answers to each of the questions and the implementation you provide.
Note: Code and Markdown cells can be executed using the Shift + Enter keyboard shortcut. Markdown cells can be edited by double-clicking the cell to enter edit mode.
The rubric contains optional "Stand Out Suggestions" for enhancing the project beyond the minimum requirements. If you decide to pursue the "Stand Out Suggestions", you should include the code in this IPython notebook.
In this notebook, you will make the first steps towards developing an algorithm that could be used as part of a mobile or web app. At the end of this project, your code will accept any user-supplied image as input. If a dog is detected in the image, it will provide an estimate of the dog's breed. If a human is detected, it will provide an estimate of the dog breed that is most resembling. The image below displays potential sample output of your finished project (... but we expect that each student's algorithm will behave differently!).
In this real-world setting, you will need to piece together a series of models to perform different tasks; for instance, the algorithm that detects humans in an image will be different from the CNN that infers dog breed. There are many points of possible failure, and no perfect algorithm exists. Your imperfect solution will nonetheless create a fun user experience!
We break the notebook into separate steps. Feel free to use the links below to navigate the notebook.
In the code cell below, we import a dataset of dog images. We populate a few variables through the use of the load_files
function from the scikit-learn library:
train_files
, valid_files
, test_files
- numpy arrays containing file paths to imagestrain_targets
, valid_targets
, test_targets
- numpy arrays containing onehot-encoded classification labels dog_names
- list of string-valued dog breed names for translating labelsfrom sklearn.datasets import load_files
from keras.utils import np_utils
import numpy as np
from glob import glob
# define function to load train, test, and validation datasets
def load_dataset(path):
data = load_files(path)
dog_files = np.array(data['filenames'])
dog_targets = np_utils.to_categorical(np.array(data['target']), 133)
return dog_files, dog_targets
# load train, test, and validation datasets
train_files, train_targets = load_dataset('dogImages/train')
valid_files, valid_targets = load_dataset('dogImages/valid')
test_files, test_targets = load_dataset('dogImages/test')
# load list of dog names
dog_names = [item[20:-1] for item in sorted(glob("dogImages/train/*/"))]
# print statistics about the dataset
print('There are %d total dog categories.' % len(dog_names))
print('There are %s total dog images.\n' % len(np.hstack([train_files, valid_files, test_files])))
print('There are %d training dog images.' % len(train_files))
print('There are %d validation dog images.' % len(valid_files))
print('There are %d test dog images.'% len(test_files))
In the code cell below, we import a dataset of human images, where the file paths are stored in the numpy array human_files
.
import random
random.seed(8675309)
# load filenames in shuffled human dataset
human_files = np.array(glob("lfw/*/*"))
random.shuffle(human_files)
# print statistics about the dataset
print('There are %d total human images.' % len(human_files))
We use OpenCV's implementation of Haar feature-based cascade classifiers to detect human faces in images. OpenCV provides many pre-trained face detectors, stored as XML files on github. We have downloaded one of these detectors and stored it in the haarcascades
directory.
In the next code cell, we demonstrate how to use this detector to find human faces in a sample image.
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# extract pre-trained face detector
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_alt.xml')
# load color (BGR) image
img = cv2.imread(human_files[3])
# convert BGR image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find faces in image
faces = face_cascade.detectMultiScale(gray)
# print number of faces detected in the image
print('Number of faces detected:', len(faces))
# get bounding box for each detected face
for (x,y,w,h) in faces:
# add bounding box to color image
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# convert BGR image to RGB for plotting
cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# display the image, along with bounding box
plt.imshow(cv_rgb)
plt.show()
Before using any of the face detectors, it is standard procedure to convert the images to grayscale. The detectMultiScale
function executes the classifier stored in face_cascade
and takes the grayscale image as a parameter.
In the above code, faces
is a numpy array of detected faces, where each row corresponds to a detected face. Each detected face is a 1D array with four entries that specifies the bounding box of the detected face. The first two entries in the array (extracted in the above code as x
and y
) specify the horizontal and vertical positions of the top left corner of the bounding box. The last two entries in the array (extracted here as w
and h
) specify the width and height of the box.
We can use this procedure to write a function that returns True
if a human face is detected in an image and False
otherwise. This function, aptly named face_detector
, takes a string-valued file path to an image as input and appears in the code block below.
# returns "True" if face is detected in image stored at img_path
def face_detector(img_path):
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray)
return len(faces) > 0
Question 1: Use the code cell below to test the performance of the face_detector
function.
human_files
have a detected human face? dog_files
have a detected human face?  You will see that our algorithm falls short of this goal, but still gives acceptable performance. We extract the file paths for the first 100 images from each of the datasets and store them in the numpy arrays human_files_short
and dog_files_short
.
Answer:
human_files_short = human_files[:100]
dog_files_short = train_files[:100]
# Do NOT modify the code above this line.
## TODO: Test the performance of the face_detector algorithm
## on the images in human_files_short and dog_files_short.
def count_humans(files):
c = 0
for i in files:
if face_detector(i):
c+=1
return c
print("human face detected in human files %d %%"% count_humans(human_files_short))
print("human face detected in dog files %d %%"% count_humans(dog_files_short))
Question 2: This algorithmic choice necessitates that we communicate to the user that we accept human images only when they provide a clear view of a face (otherwise, we risk having unneccessarily frustrated users!). In your opinion, is this a reasonable expectation to pose on the user? If not, can you think of a way to detect humans in images that does not necessitate an image with a clearly presented face?
Answer:
We suggest the face detector from OpenCV as a potential way to detect human images in your algorithm, but you are free to explore other approaches, especially approaches that make use of deep learning :). Please use the code cell below to design and test your own face detection algorithm. If you decide to pursue this optional task, report performance on each of the datasets.
Face detection algorithm on the LFW dataset using the OpenCV algorithm with Haar cascades for face detection obtained 100% accuracy when tested with human files data. This indicates the algorithm is appropriate as a technique for detecing human faces.
When used on dog files, it also scored a non-negligable accuracy of 11%. One theory is that the image also contained a human face. Alternatively, the features defined by the model may be shared between human faces and dog faces.  These might be detected in dogs as well without further distinction.
## As reference below are the images of dogs for which the model detected a human face
for i in dog_files_short:
if face_detector(i):
img = cv2.imread(i)
plt.imshow(img)
plt.show()
In this section, we use a pre-trained ResNet-50 model to detect dogs in images. Our first line of code downloads the ResNet-50 model, along with weights that have been trained on ImageNet, a very large, very popular dataset used for image classification and other vision tasks. ImageNet contains over 10 million URLs, each linking to an image containing an object from one of 1000 categories. Given an image, this pre-trained ResNet-50 model returns a prediction (derived from the available categories in ImageNet) for the object that is contained in the image.
from keras.applications.resnet50 import ResNet50
# define ResNet50 model
ResNet50_model = ResNet50(weights='imagenet')
When using TensorFlow as backend, Keras CNNs require a 4D array (which we'll also refer to as a 4D tensor) as input, with shape
$$ (\text{nb_samples}, \text{rows}, \text{columns}, \text{channels}), $$
where nb_samples
corresponds to the total number of images (or samples), and rows
, columns
, and channels
correspond to the number of rows, columns, and channels for each image, respectively.
The path_to_tensor
function below takes a string-valued file path to a color image as input and returns a 4D tensor suitable for supplying to a Keras CNN. The function first loads the image and resizes it to a square image that is $224 \times 224$ pixels. Next, the image is converted to an array, which is then resized to a 4D tensor. In this case, since we are working with color images, each image has three channels. Likewise, since we are processing a single image (or sample), the returned tensor will always have shape
$$ (1, 224, 224, 3). $$
The paths_to_tensor
function takes a numpy array of string-valued image paths as input and returns a 4D tensor with shape
$$ (\text{nb_samples}, 224, 224, 3). $$
Here, nb_samples
is the number of samples, or number of images, in the supplied array of image paths. It is best to think of nb_samples
as the number of 3D tensors (where each 3D tensor corresponds to a different image) in your dataset!
from keras.preprocessing import image
from tqdm import tqdm
def path_to_tensor(img_path):
# loads RGB image as PIL.Image.Image type
img = image.load_img(img_path, target_size=(224, 224))
# convert PIL.Image.Image type to 3D tensor with shape (224, 224, 3)
x = image.img_to_array(img)
# convert 3D tensor to 4D tensor with shape (1, 224, 224, 3) and return 4D tensor
return np.expand_dims(x, axis=0)
def paths_to_tensor(img_paths):
list_of_tensors = [path_to_tensor(img_path) for img_path in tqdm(img_paths)]
return np.vstack(list_of_tensors)
Getting the 4D tensor ready for ResNet-50, and for any other pre-trained model in Keras, requires some additional processing. First, the RGB image is converted to BGR by reordering the channels. All pre-trained models have the additional normalization step that the mean pixel (expressed in RGB as $[103.939, 116.779, 123.68]$ and calculated from all pixels in all images in ImageNet) must be subtracted from every pixel in each image. This is implemented in the imported function preprocess_input
. If you're curious, you can check the code for preprocess_input
here.
Now that we have a way to format our image for supplying to ResNet-50, we are now ready to use the model to extract the predictions. This is accomplished with the predict
method, which returns an array whose $i$-th entry is the model's predicted probability that the image belongs to the $i$-th ImageNet category. This is implemented in the ResNet50_predict_labels
function below.
By taking the argmax of the predicted probability vector, we obtain an integer corresponding to the model's predicted object class, which we can identify with an object category through the use of this dictionary.
from keras.applications.resnet50 import preprocess_input, decode_predictions
def ResNet50_predict_labels(img_path):
# returns prediction vector for image located at img_path
img = preprocess_input(path_to_tensor(img_path))
return np.argmax(ResNet50_model.predict(img))
While looking at the dictionary, you will notice that the categories corresponding to dogs appear in an uninterrupted sequence and correspond to dictionary keys 151-268, inclusive, to include all categories from 'Chihuahua'
to 'Mexican hairless'
. Thus, in order to check to see if an image is predicted to contain a dog by the pre-trained ResNet-50 model, we need only check if the ResNet50_predict_labels
function above returns a value between 151 and 268 (inclusive).
We use these ideas to complete the dog_detector
function below, which returns True
if a dog is detected in an image (and False
if not).
### returns "True" if a dog is detected in the image stored at img_path
def dog_detector(img_path):
prediction = ResNet50_predict_labels(img_path)
return ((prediction <= 268) & (prediction >= 151))
Question 3: Use the code cell below to test the performance of your dog_detector
function.
human_files_short
have a detected dog? dog_files_short
have a detected dog?Answer:
### TODO: Test the performance of the dog_detector function
### on the images in human_files_short and dog_files_short.
def count_dogs(files):
c = 0
for i in files:
if dog_detector(i):
c+=1
return c
print("Dog detected in human files %d %%"% count_dogs(human_files_short))
print("Dog detected in dog files %d %%"% count_dogs(dog_files_short))
Now that we have functions for detecting humans and dogs in images, we need a way to predict breed from images. In this step, you will create a CNN that classifies dog breeds. You must create your CNN from scratch (so, you can't use transfer learning yet!), and you must attain a test accuracy of at least 1%. In Step 5 of this notebook, you will have the opportunity to use transfer learning to create a CNN that attains greatly improved accuracy.
Be careful with adding too many trainable layers! More parameters means longer training, which means you are more likely to need a GPU to accelerate the training process. Thankfully, Keras provides a handy estimate of the time that each epoch is likely to take; you can extrapolate this estimate to figure out how long it will take for your algorithm to train.
We mention that the task of assigning breed to dogs from images is considered exceptionally challenging. To see why, consider that even a human would have great difficulty in distinguishing between a Brittany and a Welsh Springer Spaniel.
| Brittany | Welsh Springer Spaniel |
|---|---|
It is not difficult to find other dog breed pairs with minimal inter-class variation (for instance, Curly-Coated Retrievers and American Water Spaniels).
| Curly-Coated Retriever | American Water Spaniel |
|---|---|
Likewise, recall that labradors come in yellow, chocolate, and black. Your vision-based algorithm will have to conquer this high intra-class variation to determine how to classify all of these different shades as the same breed.
| Yellow Labrador | Chocolate Labrador | Black Labrador |
|---|---|---|
We also mention that random chance presents an exceptionally low bar: setting aside the fact that the classes are slightly imabalanced, a random guess will provide a correct answer roughly 1 in 133 times, which corresponds to an accuracy of less than 1%.
Remember that the practice is far ahead of the theory in deep learning. Experiment with many different architectures, and trust your intuition. And, of course, have fun!
We rescale the images by dividing every pixel in every image by 255.
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
# pre-process the data for Keras
train_tensors = paths_to_tensor(train_files).astype('float32')/255
valid_tensors = paths_to_tensor(valid_files).astype('float32')/255
test_tensors = paths_to_tensor(test_files).astype('float32')/255
Create a CNN to classify dog breed. At the end of your code cell block, summarize the layers of your model by executing the line:
model.summary()
We have imported some Python modules to get you started, but feel free to import as many modules as you need. If you end up getting stuck, here's a hint that specifies a model that trains relatively fast on CPU and attains >1% test accuracy in 5 epochs:
Question 4: Outline the steps you took to get to your final CNN architecture and your reasoning at each step. If you chose to use the hinted architecture above, describe why you think that CNN architecture should work well for the image classification task.
Answer:
CNN architectures will have one or more convolutional layer to filter out features that are detected in an image. The output of convolutional layers will encode the spatial information as a features. A feature list is produced by flattening the output of the convolutional layer so that they can be combined (as input) by a fully connected or dense layer. The fully connected layer then makes the final decision on what the output is and how they compare to the labels.
- step 1: Create model
- step 2: add convolutional layer(s) to add filters
- step 3: add pooling layers(2) to manage dimensionality
- step 4: flatten and add fully connected layer(s)
I looked at the suggested architecture to create my CNN architecture from scratch. Understanding that it creates a feature depth of up to 64. The final dense layer finds the probabilities for the combination of features and categorizes them within 133 posibilties (labels).
from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D
from keras.layers import Dropout, Flatten, Dense
from keras.models import Sequential
### Following hinted CNN architecture to discover in the image a hierarchy of spatial patterns
model = Sequential()
## first convolutional layer to detect patterns from original image by adding 16 filters
## of size 2x2, using default stride of 1. This will increse the depth of the data (see shape)
## The information on the edges of image is not interesting and no padding is added.
model.add(Conv2D(filters=16, kernel_size=2, padding='valid', activation='relu', input_shape=(224, 224, 3)))
## We then reduce dimensionality introduced by the convolutional layer feature stack of 16
## by applying a max pooling layer, this is to remove potential overfitting caused by
## the parameter increase associated to the increase in the depth of the data.
model.add(MaxPooling2D(pool_size=2))
### A second convolutional layer tries to detect more detailed patterns with a feature stack
### of 32 filters. Once more the edges of the image is not preserved, no padding is added
model.add(Conv2D(filters=32, kernel_size=2, padding='valid', activation='relu'))
### We need to reduce dimensionality once more, as the previous layer introduced more
### parameters that may cause overfitting
model.add(MaxPooling2D(pool_size=2))
### A final convolutiona layer attempts to extract the most detailed features by forming
### a feature stack of 64 filters. Once again no padding is used.
model.add(Conv2D(filters=64, kernel_size=2, padding='valid', activation='relu'))
### The lastest layer introduced many paramteres caused by the deeper feature stack of 64,
### we reduce once more the dimensionality using a max pooling layer
model.add(MaxPooling2D(pool_size=2))
### we now use a global average pooling layer to flatten the data, this reduces the
### the dimensinality to a vector as no more spatial information is discoverable, instead
### the encoded data will contains feature data.
model.add(GlobalAveragePooling2D())
### We can now feed the vector data into a fully connected layer that will combine the
### input features and use a softmax activation to produce the probability of
### the data be associated to a category out of the 133 classes of dog breed.
model.add(Dense(133, activation='softmax'))
model.summary()
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
Train your model in the code cell below. Use model checkpointing to save the model that attains the best validation loss.
You are welcome to augment the training data, but this is not a requirement.
from keras.callbacks import ModelCheckpoint
### TODO: specify the number of epochs that you would like to use to train the model.
epochs = 50
### Do NOT modify the code below this line.
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.from_scratch.hdf5',
verbose=1, save_best_only=True)
model.fit(train_tensors, train_targets,
validation_data=(valid_tensors, valid_targets),
epochs=epochs, batch_size=20, callbacks=[checkpointer], verbose=1)
from keras.callbacks import ModelCheckpoint
model.load_weights('saved_models/weights.best.from_scratch.hdf5')
Try out your model on the test dataset of dog images. Ensure that your test accuracy is greater than 1%.
# get index of predicted dog breed for each image in test set
dog_breed_predictions = [np.argmax(model.predict(np.expand_dims(tensor, axis=0))) for tensor in test_tensors]
# report test accuracy
test_accuracy = 100*np.sum(np.array(dog_breed_predictions)==np.argmax(test_targets, axis=1))/len(dog_breed_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
bottleneck_features = np.load('bottleneck_features/DogVGG16Data.npz')
train_VGG16 = bottleneck_features['train']
valid_VGG16 = bottleneck_features['valid']
test_VGG16 = bottleneck_features['test']
The model uses the the pre-trained VGG-16 model as a fixed feature extractor, where the last convolutional output of VGG-16 is fed as input to our model. We only add a global average pooling layer and a fully connected layer, where the latter contains one node for each dog category and is equipped with a softmax.
VGG16_model = Sequential()
VGG16_model.add(GlobalAveragePooling2D(input_shape=train_VGG16.shape[1:]))
VGG16_model.add(Dense(133, activation='softmax'))
VGG16_model.summary()
VGG16_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.VGG16.hdf5',
verbose=1, save_best_only=True)
VGG16_model.fit(train_VGG16, train_targets,
validation_data=(valid_VGG16, valid_targets),
epochs=20, batch_size=20, callbacks=[checkpointer], verbose=1)
VGG16_model.load_weights('saved_models/weights.best.VGG16.hdf5')
Now, we can use the CNN to test how well it identifies breed within our test dataset of dog images. We print the test accuracy below.
# get index of predicted dog breed for each image in test set
VGG16_predictions = [np.argmax(VGG16_model.predict(np.expand_dims(feature, axis=0))) for feature in test_VGG16]
# report test accuracy
test_accuracy = 100*np.sum(np.array(VGG16_predictions)==np.argmax(test_targets, axis=1))/len(VGG16_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
from extract_bottleneck_features import *
def VGG16_predict_breed(img_path):
# extract bottleneck features
bottleneck_feature = extract_VGG16(path_to_tensor(img_path))
# obtain predicted vector
predicted_vector = VGG16_model.predict(bottleneck_feature)
# return dog breed that is predicted by the model
return dog_names[np.argmax(predicted_vector)]
You will now use transfer learning to create a CNN that can identify dog breed from images. Your CNN must attain at least 60% accuracy on the test set.
In Step 4, we used transfer learning to create a CNN using VGG-16 bottleneck features. In this section, you must use the bottleneck features from a different pre-trained model. To make things easier for you, we have pre-computed the features for all of the networks that are currently available in Keras:
The files are encoded as such:
Dog{network}Data.npz
where {network}
, in the above filename, can be one of VGG19
, Resnet50
, InceptionV3
, or Xception
. Pick one of the above architectures, download the corresponding bottleneck features, and store the downloaded file in the bottleneck_features/
folder in the repository.
In the code block below, extract the bottleneck features corresponding to the train, test, and validation sets by running the following:
bottleneck_features = np.load('bottleneck_features/Dog{network}Data.npz')
train_{network} = bottleneck_features['train']
valid_{network} = bottleneck_features['valid']
test_{network} = bottleneck_features['test']
### TODO: Obtain bottleneck features from another pre-trained CNN.
bottleneck_features = np.load('bottleneck_features/DogResnet50Data.npz')
train_Resnet50 = bottleneck_features['train']
valid_Resnet50 = bottleneck_features['valid']
test_Resnet50 = bottleneck_features['test']
Create a CNN to classify dog breed. At the end of your code cell block, summarize the layers of your model by executing the line:
<your model's name>.summary()
Question 5: Outline the steps you took to get to your final CNN architecture and your reasoning at each step. Describe why you think the architecture is suitable for the current problem.
Answer:
Using transfer learning technique, we take advantage of pre-trained models with acceptable scores and criterias by the use of their trained model weights. We flatten the data into a vector of features using a global average pooling layer and then cater to a specific classification.
The pretrained model's weight applied to the image are now a list features with no spatial information. This list is the input to a fully connected layer that is trained to combine the features and produce probabilities associated to the desired output categories (133 dog breeds)
Using transfer learning from Resnet50 produced higher accuracy than the model obtained when using transfer learning from CNN16. To try to understand why this is the case, a potential reasoning can be made by seeing how closely aligned were the labels used to train the Resnet50 model with the ones used in our final model. Seeing how all the categories we are looking to detect with our model are contained within the labels used to train the Resnet50 model we can expect a higher association of the features to the labels of our interest (133 different of dog breed).
### TODO implementation
Resnet50_model = Sequential()
Resnet50_model.add(GlobalAveragePooling2D(input_shape=train_Resnet50.shape[1:]))
Resnet50_model.add(Dense(133, activation='softmax'))
Resnet50_model.summary()
### TODO: Compile the model.
Resnet50_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
Train your model in the code cell below. Use model checkpointing to save the model that attains the best validation loss.
You are welcome to augment the training data, but this is not a requirement.
### TODO: Train the model.
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.Resnet50.hdf5',
verbose=1, save_best_only=True)
Resnet50_model.fit(train_Resnet50, train_targets,
validation_data=(valid_Resnet50, valid_targets),
epochs=20, batch_size=20, callbacks=[checkpointer], verbose=1)
### TODO: Load the model weights with the best validation loss.
Resnet50_model.load_weights('saved_models/weights.best.Resnet50.hdf5')
Try out your model on the test dataset of dog images. Ensure that your test accuracy is greater than 60%.
### TODO: Calculate classification accuracy on the test dataset.
Resnet50_predictions = [np.argmax(Resnet50_model.predict(np.expand_dims(feature, axis=0))) for feature in test_Resnet50]
# report test accuracy
test_accuracy = 100*np.sum(np.array(Resnet50_predictions)==np.argmax(test_targets, axis=1))/len(Resnet50_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
Write a function that takes an image path as input and returns the dog breed (Affenpinscher
, Afghan_hound
, etc) that is predicted by your model.
Similar to the analogous function in Step 5, your function should have three steps:
dog_names
array defined in Step 0 of this notebook to return the corresponding breed.The functions to extract the bottleneck features can be found in extract_bottleneck_features.py
, and they have been imported in an earlier code cell. To obtain the bottleneck features corresponding to your chosen CNN architecture, you need to use the function
extract_{network}
where {network}
, in the above filename, should be one of VGG19
, Resnet50
, InceptionV3
, or Xception
.
### TODO: Write a function that takes a path to an image as input
### and returns the dog breed that is predicted by the model.
def Resnet50_predict_breed(img_path):
# extract bottleneck features
bottleneck_feature = extract_Resnet50(path_to_tensor(img_path))
# obtain predicted vector
predicted_vector = Resnet50_model.predict(bottleneck_feature)
# return dog breed that is predicted by the model
return dog_names[np.argmax(predicted_vector)]
Write an algorithm that accepts a file path to an image and first determines whether the image contains a human, dog, or neither. Then,
You are welcome to write your own functions for detecting humans and dogs in images, but feel free to use the face_detector
and dog_detector
functions developed above. You are required to use your CNN from Step 5 to predict dog breed.
Some sample output for our algorithm is provided below, but feel free to design your own user experience!
### TODO: Write your algorithm.
### Feel free to use as many code cells as needed.
# First test out with the use of the transfer model obtained with Resnet50
def detect_withResnet(filepath):
if dog_detector(filepath):
return "Dog: " + Resnet50_predict_breed(filepath)
elif face_detector(filepath):
return "Resemble: " + Resnet50_predict_breed(filepath)
else:
return "no face or dog is detected"
def myCNN_predict_breed(filepath):
# extract features
features = path_to_tensor(filepath)
# obtain predicted vector
predicted_vector = model.predict(features)
# return dog breed that is predicted by the model
return dog_names[np.argmax(predicted_vector)]
# Use own scratch CNN to predict breed
def detect_withmyCNN(filepath):
if dog_detector(filepath):
return "Dog: "+ myCNN_predict_breed(filepath)
elif face_detector(filepath):
return "Resemble: " + myCNN_predict_breed(filepath)
else:
return "no face or dog is detected"
In this section, you will take your new algorithm for a spin! What kind of dog does the algorithm think that you look like? If you have a dog, does it predict your dog's breed accurately? If you have a cat, does it mistakenly think that your cat is a dog?
Test your algorithm at least six images on your computer. Feel free to use any images you like. Use at least two human and two dog images.
Question 6: Is the output better than you expected :) ? Or worse :( ? Provide at least three possible points of improvement for your algorithm.
Answer:
MyCNN model is created from scratch following a simple architecture of 3 Convolutional layers with 3 max pooling layers with a final dense layer for the categorization of features. It reaches a feature depth of 64 and yields a low performance of 10% accuracy. In comparison, the model that is using transfer learning from Resnet50 achieves over 80% accuracy. This is mostly in part due to the increased complexity of the architecture in the Resnet50 model.
There are many ways of improving myCNN. One way is to update the architecture to add more convolutional layers to identify more features. This will require more resources for its training time. To tackle this cost, we need to look at ways to mitigate training complexity; as suggested, with the use of a different activation function: elu or the use of batch normalization.
Experimenting with other hyperparameters may also improve accuracy, for example another suggestion received was setting the weights initializers.
## TODO: Execute your algorithm from Step 6 on
## at least 6 images on your computer.
## Feel free to use as many code cells as needed.
detect_withmyCNN("images/sample_dog_output.png")
## TODO: Execute your algorithm from Step 6 on
## at least 6 images on your computer.
## Feel free to use as many code cells as needed.
detect_withResnet("images/sample_dog_output.png")
images = sorted(glob("samples/*"))
predictionMyCNN = []
predictionRN = []
for i in images:
predictionMyCNN.append(detect_withmyCNN(i))
predictionRN.append(detect_withResnet(i))
import pandas as pd
r = pd.DataFrame({"file":images, "MyCNN": predictionMyCNN, "Resnet50":predictionRN})
r


Ken Holle
Constable Precinct 1
Years serving: x
Constable since: 2012
Building a safe community for you
Constable Precinct 1
Years serving: x
Constable since: 2012
Building a safe community for you
The Texas constable is provided for in the Texas Constitution of 1876 (Article 5, Section 18), which calls for the election of a constable in each Texas precinct of a county, and counties may have between one and eight precincts each depending on their population.
Precinct
Serving
Experience
Deputy Constable Precinct 1
Years serving: x
Constable since: 2012
Building a safe community for you
The Texas constable is provided for in the Texas Constitution of 1876 (Article 5, Section 18), which calls for the election of a constable in each Texas precinct of a county, and counties may have between one and eight precincts each depending on their population.
Precinct
Serving
Experience


0.0.1
In AthenaJS, to create a new game, you extend the class Game and:
The Game
class is the central part to AthenaJS
(Object)
| Name | Description |
|---|---|
options.debug boolean?
(default false )
|
Debug will be enabled if this is true. |
options.name string?
|
The name of the game. |
options.target (string | HTMLElement)?
(default "new Dom('div')" )
|
target The DOM target of the game: this is where the game canvas elements will be added. By default the target is a new Div that is appened to the body element. |
options.showFps boolean?
(default false )
|
A little fps counter will be displayed if this is true. |
options.width number?
(default 1024 )
|
The width of the game display. |
options.height number?
(default 768 )
|
The height of the game display. |
options.resources Object?
|
An optionnal array of resources of the form:
{ id: 'unique id', type: 'image|script|map|audio', src: 'path_to_resource'}
that the scene needs.
|
Scene is an important part of AthenaJS: much like in a 3D engine, the displayed is based on the notion of scene. In order to have graphical elements into the screen, you first create a Scene, then add objects onto it.
The Scene
is used to display your objects. In AthenaJS you first add objects onto the scene.
When you scene is rendered (at 60fps), your objects appear on the screen.
Instead of creating a new scene, it is common to extend the Scene class to create your own scene.
(Object)
| Name | Description |
|---|---|
options.name string?
(default "Scene"+timestamp )
|
The name of your scene. |
options.resources Object?
|
An optional array of resources of the form:
{ id: 'unique id', type: 'image|script|map|audio', src: 'path_to_resource'}
that the scene needs.
|
options.backgrounds number?
(default 1 )
|
The number of backgrounds: a scene can have any number of backgrounds. |
options.layers number?
(default 2 )
|
The number of layers: layers are stacked above the backgrounds. |
options.foregrounds number?
(default 1 )
|
The number of foreground layers. This would typically be used for parallax scrollings. |
options.opacity number?
(default 1 )
|
The default opacity for the scene: can be usefull to have fadeIn effects when starting the scene. |
options.hudScene number?
|
Scenes can have an option
hud
scene that is automatically rendered on top of it. This allows to easily add score/status elements to games.
|
Associates the specified map with the scene: the map will then be used to render the scene. note The map can either be an instance of a Map or a class inheriting from Map, in which case
Add one ore more display objects onto the scene
These classes handle everything that's related to maps in AthenaJS. A map isn't required to create a new game.
The Map
is used to display tile-based backgrounds. It is usually initialized using a buffer containing
tiles and tilebehaviors. It has a viewport so that only a part of the map can be displayed.
A map also contains objects that are added onto the map once the viewport reaches a block
.
(Object)
| Name | Description |
|---|---|
options.src string
|
The url to an image that will be used for the tiles |
options.tileWidth number
|
The width of a tile |
options.tileHeight number
|
The height of a tile |
options.width number
|
The full width of the map |
options.height number
|
The full height of the map |
options.viewportW number
|
The width of the viewport: it is usually the same as the game width |
options.viewportH number
|
The height of the viewport: it is usually the same as the game height |
options.buffer ArrayBuffer
|
The buffer containing width * height bytes container tile numbers followed by width*height bytes for the tile behaviors |
var map = new Map({
src: 'mapTiles.jpg',
tileWidth: 32,
tileHeight 32,
width: 800,
height: 600,
buffer: new ArrayBuffer(800*600*2)
})
Sets a new destination for the viewport: this method doesn't not set it immediately but sets a new target instead: if not already moving, new move will happen at each render inside the map.move() method
Checks if tile at position x,y is TYPE.WALL
and returns true if it is a wall, false otherwise
boolean
:
Returns true if the tile is a wall, false otherwise.
Calculates and sets the object's next x position using its current x, vx and avoids tileTypes tiles (ie: walls, moving platforms)
boolean
:
Returns true if the object hit the spcified tile, false otherwise
Checks if an object is in front of a certain type of tileType, optionnaly centering the object under the tile
Used when checking if the player can climb a ladder for example
spaceX/spaceY specify how to reduce the players hitbox
(GfxObject)
The sprite to check.
(number)
The tileType to check for.
(number?
= 0
)
The x padding that is accepted: if horizontal position is +/- that spaceX, check will succeed.
(number?
= 0
)
The y padding that is accepted: if vertical position is +/- that spaceX, check will succeed.
(boolean?
= false
)
Set to true if you want to sprite to be centered on the tile.
boolean
:
True if the tile was found, false otherwise
Tests if a rectangle collapses with certain types of tiles Used when checking colligions between a sprite and walls for example
boolean
:
True if colision detected
Draws tile at pixel position (x, y) onto the specified {Canvas} context
(number)
The tile number to draw.
(CanvasContext)
The canvas rendering context to draw the tile into.
(number)
The horizontal position where to draw the tile.
(number)
The vertical position where to draw the tile.
(Boolean)
If set to true, the tile will be partially rendered
starting at scrollOffsetX. This happens if the tile is at the firstRow/firstCol of the viewport.
MapEvent handles events that are triggered on the map. Such events can be: checkpoint was reached, new wave needs to be generated, etc...
For that, the MapEvent class stores a list of items, events, switches that are on the map.
This is a default MapEvent class: games should extend MapEvent to handle whatever events they need.
In AthenaJS, any graphical objects that can be displayed and moved onto the screen inherits from GfxObject. AthenaJS comes with these Objects:
GfxObject
is the base class for objects that can be rendered on the screen.
A GfxObject
has properties like x, y, vx, vy, speed.
In order to be rendered, an object must be added onto the active scene/map.
It can also have an optional behavior which tells Athena how
to move an object at each frame.
(string)
The type of object: this describes the type of object
(Object)
| Name | Description |
|---|---|
options.objectId string?
|
The id of the object. The defaults is type + random timestamp. |
options.collideGroup number?
(default 0 )
|
The type of collision to use for the object. |
options.master boolean?
(default false )
|
Set to true if the object should be the master. |
options.visible boolean?
(default true )
|
An invisible object isn't rendered onto the screen. |
Performs an animation on the object using one of the defined {FX} effects
Effects change the object size/position using an interpolation function.
Athena has the following effects:
(String)
the name of the effect to use.
Promise
:
a promise that will be fullfilled when the effect has been completed
This method is called when drawing an object
GfxObject is a virtual object so its drawing method does nothing
Every Object inheriting from GfxObject should implement its own draw method.
(CanvasContext)
the target canvas rendering context.
(Boolean)
Debug is set to true if the game is being debugged.
This class extends {GfxObject} to implement 2D sprites using an image sprite sheet.
A sprite can have an infinite number of animations. Each animation can have a different frameDuration and any number of frames. Each frame may have a different size and a different hitbox
Extends GfxObject
let mySprite = new Sprite('gem', {
imageSrc: 'objects',
x: options.x,
y: options.y,
pool: options.pool,
canCollide: true,
collideGroup: 1,
animations: {
mainLoop: {
frameDuration: 4,
frames:[{
offsetX: 136,
offsetY: 189,
w: 31,
h: 31,
hitBox: {
x: 0,
y: 0,
x2: 31,
y2: 31
},
plane: 0
},
{
offsetX: 170,
offsetY: 189,
w: 31,
h: 31,
hitBox: {
x: 0,
y: 0,
x2: 31,
y2: 31
},
plane: 0
}],
loop: 1
}
}
});
WIP: updateFlipAnimation
It's possible to define a new animation that is simply the flip of another one This method copies the frames of the source animation and flips them
Goes to the next animation frame
When reaching the last frame, the next frame will depend on animation.loop property:
The BitmapText class allows to use a spritesheet as a font to draw text onto the screen
Extends GfxObject
(String)
The type of the sprite.
(Object)
The options describing the BitmapText.
| Name | Description |
|---|---|
options.imageSrc String
|
The path to the spritesheet file. |
options.offsetX Number?
(default 0 )
|
The optional horizontal offset at which to start getting bitmap characters inside the spritesheet. |
options.bmStartY Number?
(default 0 )
|
The optinal vertical offset at which to start getting bitmap characters. |
(Number)
the width of a character in pixels.
(Number)
The height of a character in pixels.
let myFont = new BitmapText('myFont', {
offsetX: 34,
bmStartY: 36,
charWidth: 16,
charHeight: 18,
imageSrc: 'font'
});
Draws the specified line onto the screen
bitmapText.drawLine({
x: 0,
y: 0,
text: 'hi there'
})
Basic class for displaying text using Canvas
Extends GfxObject
(String)
The type of the graphic object
(Object)
| Name | Description |
|---|---|
options.text String?
(default undefined )
|
The initial text. Can be changed later using Text.setText(). |
options.w Number?
(default 0 )
|
The width of the text. |
options.h Number?
(default 0 )
|
The height of the text. |
options.fontFace String?
(default "Arial" )
|
The font to use to draw the text. |
options.fontStyle String?
(default "normal" )
|
The style of the font. |
options.fontSize String?
(default "18px" )
|
The size of the font. |
options.fontWeight String?
(default "normal" )
|
The weight of the font. |
options.align String?
(default "center" )
|
How to align the text when rendered. |
options.color String?
(default "white" )
|
The color to use when rendering the text. |
let myText = new Text({
text: 'hello',
fontFace: 'Verdana',
fontStyle: 'bold',
fontSize: '24px'
})
The menu class allows to quickly add text menu to an Athena Scene
Each menu entry is called menuItem and is a simple object with the following properties: { text: 'menu text', selectable: true|false, active: true|false, visible: true|false }
Extends GfxObject
(String)
The type of object.
(Object)
| Name | Description |
|---|---|
options.title String?
(default "Menu Title" )
|
The title of the menu. |
options.color String?
(default "black" )
|
The color of the menu. |
options.menuItems Array?
(default [] )
|
The menu items to add. |
options.selectedColor String?
(default "red" )
|
The default color to use for the selected menu item. |
let myMenu = new Menu('mainMenu', {
title: 'Gods JS',
color: 'white',
menuItems: [
{
text: '> Start Game',
selectable: true,
visible: true,
active: true
},
{
text: '> Cannot Select ;)',
selectable: true,
visible: true
}]
})
Behaviors define the way graphical objects move onto the screen, like enemies moving left/right, etc... PlayerMove is behavior that is controlled by the player, using keyboard input. There are a few built-in behaviors but they can be extended and any behavior can be attached to any graphical object.
Base class for behaviors.
A behavior is a class that describes how a graphical object moves during the time.
Every behavior should implement these two methods:
(Sprite)
The sprite to attach the behavior to.
(InputManager)
A reference to the InputManager.
(Object)
An hash with behavior-specific properties.
| Name | Description |
|---|---|
options.gravity Number?
(default 0 )
|
The object's gravity. |
options.vx Number?
(default 0 )
|
The object's horizontal velocity. |
options.vy Number?
(default 0 )
|
The object's vertical velocity. |
options.onVXChange Function?
(default undefined )
|
An optional callback to call when changing vx direction |
options.onVYChange Function?
(default undefined )
|
An optional callback to call when changing vy direction |
GroundMove is a simple behavior that causes an object to move along the horizontal axis until a wall or an hole is reached.
Extends Behavior
(Sprite)
The sprite to attach the behavior to.
(InputManager)
A reference to the InputManager.
A Path is a special behavior that uses a pre-defined (recorded) path to move an object.
Extends Behavior
(Sprite)
The sprite to attach the behavior to.
(InputManager)
A reference to the InputManager.
(Object)
The options of the behavior.
| Name | Description |
|---|---|
options.nodes Array
|
The nodes of the path: a simple array with nodes [ 0 ] = vx, nodes [ 1 ] = vy, nodes [ 2 ] = vx, nodes [ 3 ] = vy,... |
options.reverse Boolean
|
Set to true so that when the end of the path is reached, movement goes backwards. |
PlayerMove is a behavior that is controlled by the player using keyboard/touch events.
To have a sprite controlled by the user you can simply attach this behavior.
Extends Behavior
(Sprite)
The sprite to attach the behavior to.
(InputManager)
A reference to the InputManager
(Object)
Parameters specifics to the behavior
| Name | Description |
|---|---|
options.startMovement String?
(default "idle"" )
|
The initial behavior state. |
options.direction String?
(default "right" )
|
The initial direction. |
options.lookDirection String?
(default "left" )
|
The initial look direction, can be different than direction. |
Simple behavior that makes an object bounce on the ground
Extends Behavior
(Sprite)
The sprite to attach the behavior to.
(InputManager)
A reference to the InputManager.
(Object)
The options of the behavior.
| Name | Description |
|---|---|
options.elasticity Number?
(default 0.80 )
|
The elasticity: the closer it is to 1, the higher the bounce. |
options.onEnd Function?
(default undefined )
|
An optional callback to execute when the object stops bouncing. |
options.onGround Function?
(default undefined )
|
An optional callback to execute each time the object touches the ground. |
sprite.setBehavior('simplefall', {
gravity: 0.3,
onEnd: () => {
this.moving = false;
},
onGround: function() {
AM.play('bounce');
}
});
The move handler that gets executed at each move loop.
Simply calculates the next vertical position using current velocity. Each time the object reaches the ground, it bounces a little less, using the elasticity property, until it reaches the ground and stops bouncing.
(any)
Simple behavior that moves horizontally until a wall is reached.
Extends Behavior
(Sprite)
The sprite to attach the behavior to.
(InputManager)
A reference to the InputManager.
Athena comes with several 'managers':
AudioManager
handles playback of audio files loaded using the ResourceManager
(Object)
: An hash that stores in-use sounds.
The key is the id of the sound.
(boolean)
: This is set to false when sound playback is disabled.
Handles keyboard input (joystick input doesn't work correctly yet).
Key presses are stored in a simple hash this.keyPressed with keyCode as key, and attached handlers are stored in another hash this.keyCb.
The InputManager can also be used to record keystrokes which can then be played back to produce game demos for example.
// example state of InputManager.keyPressed where `up` key is down and `down` key has just been released:
{ 32: true, 40: false}
Handles resource loading at runtime
Resources are loaded and retrieved using this manager.
The ResourceManager can load at runtime the folowing types of resources:
Allocates a new resource from the pool
This method creates a new instance of the JavaScript object, retrieving it from the pool if the object supports it. If it does not it simply uses new to generate a new instance
(String)
The id of the resource for which to create a new instance.
Object
:
a new instance of the specified object.
Add new resource(s) into the specified group
(String)
the name of the group to add the resources into
Deferred
:
a new Deferred that will be resolved once the
resources have been loaded.
Note This method only adds the resources to the group but do not load them.
ResourceManager.addResources({
id: 'sprites',
type: 'image',
src: './sprites/gem.png'
}, "sprites");
// resource type can be image|map|audio
These classes provide Core functionnality to AthenaJS
Dom is a very simple jQuery-like object that allows to manipulate a collection of DOM elements.
As in jQuery, you may manipulate Dom collections using []
(any)
Append current collection to the element with a specific selector
((String | HTMLElement))
Target element where to append selected elements.
It can either be a CSS selector or a DOM HTMLElement.
Dom
:
this
Simple wrapper for ES6 native Promise
Pool support for AthenaJS
This objects allows to defined and use pools for any type of object
Object that allows sending & receving binary data
microevents.js - https://github.com/jeromeetienne/microevent.js
build the canvas for joystick base
build the canvas for joystick stick
Boolean
:
true if touchscreen is currently available, false otherwise


| OLD line(s): 763
<LineNumber>Schedule A Line 9(a)</LineNumber> | NEW line(s): 763
<LineNumber>Schedule A Line 9a(a)</LineNumber> |
| OLD line(s): 767
| NEW line(s): 768,787
<!-- Extraordinary Items 1st 4 Months Income --> <xsd:element name="First4MnthIncmExtraordnryItems" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Extraordinary items 1st 4 months income</Description> <LineNumber>Schedule A Line 9b(a)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> <!-- Total Taxable Income for 1st 4 months --> <xsd:element name="First4MonthsTotalTaxableIncome" type="LargeRatioType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Add lines 9a(a) and 9b(a)</Description> <LineNumber>Schedule A Line 9c(a)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> |
| OLD line(s): 772
<Description>Figure the tax on the amount on line 9 using the instructions for Form 1120,</Description> | NEW line(s): 792
<Description>Figure the tax on the amount on line 9c(a) using the instructions for Form 1120,</Description> |
| OLD line(s): 973
<LineNumber>Schedule A Line 9(b)</LineNumber> | NEW line(s): 993
<LineNumber>Schedule A Line 9a(b)</LineNumber> |
| OLD line(s): 977
| NEW line(s): 998,1017
<!-- Extraordinary Items 1st 6 Months Income --> <xsd:element name="First6MnthIncmExtraordnryItems" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Extraordinary items 1st 6 months income</Description> <LineNumber>Schedule A Line 9b(b)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> <!-- Total Taxable Income for 1st 6 Months --> <xsd:element name="First6MonthsTotalTaxableIncome" type="LargeRatioType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Add lines 9a(b) and 9b(b)</Description> <LineNumber>Schedule A Line 9c(b)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> |
| OLD line(s): 982
<Description>Figure the tax on the amount on line 9 using the instructions for Form 1120.</Description> | NEW line(s): 1022
<Description>Figure the tax on the amount on line 9c(b) using the instructions for Form 1120.</Description> |
| OLD line(s): 1183
<LineNumber>Schedule A Line 9(c)</LineNumber> | NEW line(s): 1223
<LineNumber>Schedule A Line 9a(c)</LineNumber> |
| OLD line(s): 1187
| NEW line(s): 1228,1247
<!-- Extraordinary Items 1st 9 Months Income --> <xsd:element name="First9MnthIncmExtraordnryItems" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Extraordinary items 1st 9 months income</Description> <LineNumber>Schedule A Line 9b(c)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> <!-- Total Taxable Income for 1st 9 Months --> <xsd:element name="First9MonthsTotalTaxableIncome" type="LargeRatioType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Add lines 9a(c) and 9b(c)</Description> <LineNumber>Schedule A Line 9c(c)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> |
| OLD line(s): 1192
<Description>Figure the tax on the amount on line 9 using the instructions for Form 1120.</Description> | NEW line(s): 1252
<Description>Figure the tax on the amount on line 9c(c) using the instructions for Form 1120.</Description> |
| OLD line(s): 1393
<LineNumber>Schedule A Line 9(d)</LineNumber> | NEW line(s): 1453
<LineNumber>Schedule A Line 9a(d)</LineNumber> |
| OLD line(s): 1397
| NEW line(s): 1458,1477
<!-- Extraordinary Items Entire Year Income --> <xsd:element name="EntireYearIncmExtraordnryItem" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Extraordinary items entire year income</Description> <LineNumber>Schedule A Line 9b(d)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> <!-- Total Taxable Income for Entire Year --> <xsd:element name="EntireYearTotalTaxableIncome" type="LargeRatioType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Add lines 9a(d) and 9b(d)</Description> <LineNumber>Schedule A Line 9c(d)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> |
| OLD line(s): 1402
<Description>Figure the tax on the amount on line 9 using the instructions for Form 1120.</Description> | NEW line(s): 1482
<Description>Figure the tax on the amount on line 9c(d) using the instructions for Form 1120.</Description> |
| OLD line(s): 1508
<LineNumber>Schedule A Line 23a</LineNumber> | NEW line(s): 1588
<LineNumber>Schedule A Line 23a(a)</LineNumber> |
| OLD line(s): 1512
| NEW line(s): 1593,1612
<!-- Extraordinary Items for Annualization Period #1 --> <xsd:element name="ExtraordinaryItems1" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Extraordinary items for annualization period #1</Description> <LineNumber>Schedule A Line 23b(a)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> <!-- Total Taxable Income for Annualization Period #1 --> <xsd:element name="AnnualizedTotalTaxableIncome1" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Add lines 23a(a) and 23b(a)</Description> <LineNumber>Schedule A Line 23c(a)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> |
| OLD line(s): 1517
<Description>Figure the tax on the amount in each column on line 23 using the instructions for Form 1120.</Description> | NEW line(s): 1617
<Description>Figure the tax on the amount in each column on line 23c using the instructions for Form 1120.</Description> |
| OLD line(s): 1630
<LineNumber>Schedule A Line 23b</LineNumber> | NEW line(s): 1730
<LineNumber>Schedule A Line 23a(b)</LineNumber> |
| OLD line(s): 1634
| NEW line(s): 1735,1754
<!-- Extraordinary Items for Annualization Period #2 --> <xsd:element name="ExtraordinaryItems2" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Extraordinary items for annualization period #2</Description> <LineNumber>Schedule A Line 23b(b)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> <!-- Total Taxable Income for Annualization Period #2 --> <xsd:element name="AnnualizedTotalTaxableIncome2" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Add lines 23a(b) and 23b(b)</Description> <LineNumber>Schedule A Line 23c(b)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> |
| OLD line(s): 1639
<Description>Figure the tax on the amount in each column on line 23 using the instructions for Form 1120.</Description> | NEW line(s): 1759
<Description>Figure the tax on the amount in each column on line 23c using the instructions for Form 1120.</Description> |
| OLD line(s): 1752
<LineNumber>Schedule A Line 23c</LineNumber> | NEW line(s): 1872
<LineNumber>Schedule A Line 23a(c)</LineNumber> |
| OLD line(s): 1756
| NEW line(s): 1877,1896
<!-- Extraordinary Items for Annualization Period #3 --> <xsd:element name="ExtraordinaryItems3" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Extraordinary items for annualization period #3</Description> <LineNumber>Schedule A Line 23b(c)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> <!-- Total Taxable Income for Annualization Period #3 --> <xsd:element name="AnnualizedTotalTaxableIncome3" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Add lines 23a(c) and 23b(c)</Description> <LineNumber>Schedule A Line 23c(c)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> |
| OLD line(s): 1761
<Description>Figure the tax on the amount in each column on line 23 using the instructions for Form 1120.</Description> | NEW line(s): 1901
<Description>Figure the tax on the amount in each column on line 23c using the instructions for Form 1120.</Description> |
| OLD line(s): 1874
<LineNumber>Schedule A Line 23d</LineNumber> | NEW line(s): 2014
<LineNumber>Schedule A Line 23a(d)</LineNumber> |
| OLD line(s): 1878
| NEW line(s): 2019,2038
<!-- Extraordinary Items for Annualization Period #4 --> <xsd:element name="ExtraordinaryItems4" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Extraordinary items for annualization period #4</Description> <LineNumber>Schedule A Line 23b(d)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> <!-- Total Taxable Income for Annualization Period #4 --> <xsd:element name="AnnualizedTotalTaxableIncome4" type="USAmountType" minOccurs="0"> <xsd:annotation> <xsd:documentation> <Description>Add lines 23a(d) and 23b(d)</Description> <LineNumber>Schedule A Line 23c(d)</LineNumber> </xsd:documentation> </xsd:annotation> </xsd:element> |
| OLD line(s): 1883
<Description>Figure the tax on the amount in each column on line 23 using the instructions for Form 1120.</Description> | NEW line(s): 2043
<Description>Figure the tax on the amount in each column on line 23c using the instructions for Form 1120.</Description> |


I want to make things that make a difference
I am available for hire and open to any ideas of cooperation.


|
|||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
| Interface Summary | |
| Expression | Expression represents an arbitrary expression on a bean. |
| Updater | Updater acts like an lvalue which updates the current
context bean from some text from an XML attribute or element. |
| Class Summary | |
| ClassNameExpression | ClassNameExpression returns the current class name
of the context bean |
| CollectionUpdater | Updates a Collection by adding the new value to it. |
| ConstantExpression | ConstantExpression represents a constant expression. |
| Context | Context describes the context used to evaluate
bean expressions. |
| DynaBeanExpression | An Expression that gets a property value from a DynaBean. |
| DynaBeanUpdater | Updates DynaBean 's. |
| EmptyExpression | EmptyExpression returns the same value as is passed in. |
| IteratorExpression | IteratorExpression returns an iterator over the current context. |
| MapEntryAdder | MapEntryAdder is used to add entries to a map. |
| MethodExpression | MethodExpression evaluates a method on the current bean context. |
| MethodUpdater | MethodUpdater updates the current bean context
by calling a WriteMethod with the String value from the XML attribute
or element. |
| StringExpression | StringExpression returns the current context object as a string. |
| TypedUpdater | Abstracts common features for strongly typed Updater 's. |
| VariableExpression | VariableExpression represents a variable expression such as
$foo which returns the value of the given variable. |
This package contains the system which extracts values from beans.
The mapping is created by class introspection
but the Expression
implementations
in this package inspect a particular bean instance and extract the values
used to render the bean as xml.
|
|||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |


Delicious
THE BEST FOOD BLOG ON THE WEB
For the fig-swirl: Melt butter over medium heat in a sauce pan. Add brown sugar and stirl to desolve. Halve all of the figs and toss in the sauce pan with water and lemon juice. Cook over medium heat, stirring frequently, until you have a chunky-jammy mixture. Add salt with one or two stirs, set aside and let cool completely.
Ice cream: In a small pot over medium heat, combine milk, and granulated sugar until sugar is completely dissolved and the milk is just barely lukewarm. Whisk in the egg yolks. Set mixture in the fridge and wait until the fig mixture is cooled.
Using an ice cream machine, pour liquids into the frozen basin and process according to manufacturer instructions, i.e., let spin and thicken for 20 minutes before adding mascarpone, fig jam mixture, and the nuts. Continue to process for +/- 10 minutes. Pour semi-frozen mixture into a pyrex dish or glass tupperware. Freeze for at least two hours before serving.
Food enthusiast, photography fan. Add a pinch of raw foodism and that's pretty much who I am.
SHARE RECIPE


12 December 2007
The Ministry of Health of Indonesia has announced a new case of human infection of H5N1 avian influenza. A 28-year-old female from Tangerang City, Banten Province developed symptoms on 1 December, was hospitalized on 7 December and died in an AI referral hospital on 10 December. The case worked as a road side seller of decorative plants. Poultry and poultry cages were located in the vicinity of her business. Investigations are ongoing into the source of her infection.
Of the 114 cases confirmed to date in Indonesia, 92 have been fatal.


Coverage report for UTCovTest (C:\Users\joe.snyder\Work\OSEHRA\VistA\Packages\Order Entry Results Reporting\CPRS\Testing\Tests\UTCovTest.pas).
Generated at 10/3/2014 12:24:11 PM by DelphiCodeCoverage - an open source tool for Delphi Code Coverage.
Statistics for C:\Users\joe.snyder\Work\OSEHRA\VistA\Packages\Order Entry Results Reporting\CPRS\Testing\Tests\UTCovTest.pas
| Number of lines covered | 19 |
| Number of lines with code gen | 19 |
| Line coverage | 100% |
| 1 | //--------------------------------------------------------------------------- |
| 2 | // Copyright 2012 The Open Source Electronic Health Record Agent |
| 3 | // |
| 4 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | // you may not use this file except in compliance with the License. |
| 6 | // You may obtain a copy of the License at |
| 7 | // |
| 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | // |
| 10 | // Unless required by applicable law or agreed to in writing, software |
| 11 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | // See the License for the specific language governing permissions and |
| 14 | // limitations under the License. |
| 15 | //--------------------------------------------------------------------------- |
| 16 | unit UTCovTest; |
| 17 | interface |
| 18 | uses UnitTest, TestFrameWork,SysUtils,Windows; |
| 19 | |
| 20 | implementation |
| 21 | type |
| 22 | UTCovTestTests=class(TTestCase) |
| 23 | public |
| 24 | procedure SetUp; override; |
| 25 | procedure TearDown; override; |
| 26 | |
| 27 | published |
| 28 | procedure TestCov1; |
| 29 | procedure TestCov2; |
| 30 | procedure TestCov3; |
| 31 | end; |
| 32 | |
| 33 | procedure NotRun; |
| 34 | begin |
| 35 | WriteLn('This line will never run'); |
| 36 | end; |
| 37 | procedure UTCovTestTests.SetUp; |
| 38 | begin |
| 39 | end; |
| 40 | |
| 41 | procedure UTCovTestTests.TearDown; |
| 42 | begin |
| 43 | end; |
| 44 | |
| 45 | procedure UTCovTestTests.TestCov1; |
| 46 | begin |
| 47 | { |
| 48 | Block comment lines |
| 49 | } |
| 50 | CheckEquals(1,2-1); |
| 51 | end; |
| 52 | |
| 53 | procedure UTCovTestTests.TestCov2; |
| 54 | var |
| 55 | i:DWORD; |
| 56 | begin |
| 57 | for i := 0 to 1 do |
| 58 | WriteLn( IntToStr(i)); |
| 59 | // Comment |
| 60 | CheckEquals(i,2); |
| 61 | end; |
| 62 | |
| 63 | procedure UTCovTestTests.TestCov3; |
| 64 | var |
| 65 | i : DWORD; |
| 66 | begin |
| 67 | i := 0; |
| 68 | while i < 5 do |
| 69 | i := i+1; |
| 70 | CheckEquals(i,5); |
| 71 | end; |
| 72 | |
| 73 | begin |
| 74 | UnitTest.addSuite(UTCovTestTests.Suite); |
| 75 | end. |


Review the The Eight Key Questions (8KQ) handbook produced by James Madison University then answer the questions below.
" James Madison University (JMU). 2020. 8KQ Handbook."
Which of the following is not one of the Eight Key questions used to evaluate
the ethical dimensions of a problem or situation?
There are no hints for this question


Contains the REIDS model presented in Van Moerbeke et al (2017) <doi:10.1186/s12859-017-1687-8> for the detection of alternative splicing. The method is extended by incorporating junction information for the assessment of alternative splicing. The vignette introduces the model and shows an example work flow.
| Version: | 0.1.0 |
| Depends: | R (≥ 2.10), aroma.affymetrix, aroma.core, GenomeGraphs, biomaRt |
| Imports: | data.table, RColorBrewer, MCMCpack, lmtest, methods |
| Published: | 2018-07-30 |
| Author: | Marijke Van Moerbeke |
| Maintainer: | Marijke Van Moerbeke <marijke.vanmoerbeke at uhasselt.be> |
| License: | GPL-3 |
| NeedsCompilation: | no |
| CRAN checks: | REIDS results |
| Reference manual: | REIDS.pdf |
| Vignettes: |
REIDSvignette |
| Package source: | REIDS_0.1.0.tar.gz |
| Windows binaries: | r-devel: REIDS_0.1.0.zip, r-release: REIDS_0.1.0.zip, r-oldrel: REIDS_0.1.0.zip |
| OS X binaries: | r-release: not available, r-oldrel: REIDS_0.0.1.tgz |
| Old sources: | REIDS archive |
Please use the canonical form https://CRAN.R-project.org/package=REIDS to link to this page.


This project tasked me with creating a form to collect user inputs, form validation, and v-for loops and a $router.push statement to a secret page.
This project required me to create an application that used more than one view or "route". I had to break it down into the following milestones to help me get through it and ensure nothing was missed.


JUI-F blocks highways, stages sit-ins in parts of country
by https://www.facebook.com/dunyanewsQUETTA (Dunya News) – Jamiat Ulema-e-Islam-Fazal (JUI-F) is continuing to block highways and stage sit-ins in parts of Pakistan including Karachi and Khyber Pakhtunkhwa (KP) on Friday following Plan B of Azadi March.
According to details, JUI-F’s sit-in has entered second day on the Hub River Road in Karachi and people are facing trouble as traffic between Sindh and Balochistan has partially been suspended.
The protesters set up tents on Ghotki National Highway after it started raining. Traffic is halted on the Indus Highway in Taunsa Sharif and Bannu. Nowshera GT Road has been closed in Hakimabad.
JUI-F workers have closed Shahrah-e-Resham in Mansehra and staged sit-in in Lower Dir at the Pul Chowki Chakdara. Quetta-Karachi and Quetta-DG Khan Highways have also been blocked.
The citizens are forced to use alternative routes. It has further been learnt that JUI-F has planned to lockdown the entire country after November 18.