This page contains answers to frequently asked questions about GrapheneOS. It's not
an overview of the project or a list of interesting topics about GrapheneOS. Many of
the answers would be nearly the same or identical for the latest release of the
Android Open Source Project. The goal is to provide high quality answers to some of
the most common questions about the project, so the developers and other community
members can link to these and save lots of time while also providing higher quality
answers.
GrapheneOS has official production support for the following devices:
- Pixel 6 Pro (raven)
- Pixel 6 (oriole)
- Pixel 5a (barbet)
- Pixel 5 (redfin)
- Pixel 4a (5G) (bramble)
- Pixel 4a (sunfish)
- Pixel 4 XL (coral)
- Pixel 4 (flame)
- Pixel 3a XL (bonito)
- Pixel 3a (sargo)
The following devices are end-of-life, no longer receive full security
updates and are supported via extended support releases of GrapheneOS:
- Pixel 3 XL (crosshatch)
- Pixel 3 (blueline)
We provide extended support releases as a stopgap for users to transition
to the far more secure current generation devices.
The release tags for these devices have official builds and updates
available. These devices meet the stringent privacy and security standards and
have substantial upstream and downstream hardening specific to the
devices.
Many other devices are supported by GrapheneOS at a source level, and it can be
built for them without modifications to the existing GrapheneOS source tree. Device
support repositories for the Android Open Source Project can simply be dropped into
the source tree, with at most minor modifications within them to support GrapheneOS.
In most cases, substantial work beyond that will be needed to bring the support up to
the same standards. For most devices, the hardware and firmware will prevent providing
a reasonably secure device, regardless of the work put into device support.
GrapheneOS also supports generic targets, but these aren't suitable for production
usage and are only intended for development and testing use. For mobile devices, the
generic targets simply run on top of the underlying device support code (firmware,
kernel, device trees, vendor code) rather than shipping it and keeping it updated. It
would be possible to ship generic system images with separate updates for the device
support code. However, it would be drastically more complicated to maintain and
support due to combinations of different versions and it would cause complications for
the hardening done by GrapheneOS. The motivation doesn't exist for GrapheneOS, since
full updates with deltas to minimize bandwidth can be shipped for every device and
GrapheneOS is the only party involved in providing the updates. For the same reason,
it has little use for the ability to provide out-of-band updates to system image
components including all the apps and many other components.
Some of the GrapheneOS sub-projects support other operating systems on a broader
range of devices. Device support for Auditor and AttestationServer is documented in
the overview of those projects. The
hardened_malloc project
supports nearly any Linux-based environment due to official support for musl, glibc
and Bionic along with easily added support for other environments. It can easily run
on non-Linux-based operating systems too, and supporting some like HardenedBSD is
planned but depends on contributors from those communities.
The Pixel 6 and Pixel 6 Pro are flagship phones with much nicer hardware
than previous generation devices (cameras, CPU, GPU, display, battery), 5
years of guaranteed full security updates / support and substantial security
improvements. We strongly recommend buying one of these latest generation
devices.
The cheaper Pixel 6 has extremely competitive pricing for the flagship
level hardware especially with the guaranteed long term support. Pixel 6 Pro
has 50% more memory (12GB instead of 8GB), a higher end screen, a 3rd rear
camera with 4x optical zoom and a higher end front camera. Both devices have
the same SoC (CPU, GPU, etc.) and the same main + ultrawide rear cameras. The
Pixel 6 is quite large and the Pixel 6 Pro is larger.
The following devices are reasonable choices if for some reason you can't
obtain a Pixel 6 or Pixel 6 Pro:
- Pixel 5a (barbet)
- Pixel 5 (redfin)
- Pixel 4a (5G) (bramble)
The Pixel 5a, Pixel 5 and Pixel 4a (5G) are 5th generation Pixels sharing
the same mid-range 2020 SoC. These devices have around 2-3 years before their
end-of-life date after they receive Android 14. It's likely but not guaranteed
that the Pixel 5 and 4a (5G) will have their full security support extended to
match the Pixel 5a since they use the same platform.
Despite the misleading name, the Pixel 4a (5G) is not a variant of the 4th
generation Pixel 4a which has an older mid-range 2019 SoC. The Pixel 4a was
released about 2 months before the first 5th generation devices but those are
likely to be supported more than the 3 year minimum while the Pixel 4a is very
unlikely to receive longer support due to the older SoC. GrapheneOS extended
support for 4th generation devices will end with the release of Android 14 so
there won't be much leeway provided by it for the Pixel 4a.
Devices are carefully chosen based on their merits rather than the project aiming
to have broad device support. Broad device support is counter to the aims of the
project, and the project will eventually be engaging in hardware and firmware level
improvements rather than only offering suggestions and bug reports upstream for those
areas. Much of the work on the project involves changes that are specific to different
devices, and officially supported devices are the ones targeted by most of this
ongoing work.
Devices need to be meeting the standards of the project in order to be considered as
potential targets. In addition to support for installing other operating systems,
standard hardware-based security features like the hardware-backed keystores, verified
boot, attestation and various hardware-based exploit mitigations need to be available.
Devices also need to have decent integration of IOMMUs for isolating components such
as the GPU, radios (NFC, Wi-Fi, Bluetooth, Cellular), media decode / encode, image
processor, etc., because if the hardware / firmware support is missing or broken,
there's not much that the OS can do to provide an alternative. Devices with support for
alternative operating systems as an afterthought will not be considered. Devices need
to have proper ongoing support for their firmware and software specific to the hardware
like drivers in order to provide proper full security updates too. Devices that are
end-of-life and no longer receiving these updates will not be supported.
In order to support a device, the appropriate resources also need to be available
and dedicated towards it. Releases for each supported device need to be robust and
stable, with all standard functionality working properly and testing for each of the
releases.
Hardware, firmware and software specific to devices like drivers play a huge role
in the overall security of a device. The goal of the project is not to slightly
improve some aspects of insecure devices and supporting a broad set of devices would
be directly counter to the values of the project. A lot of the low-level work also
ends up being fairly tied to the hardware.
Broader device support can only happen after the community (companies,
organizations and individuals) steps up to make substantial, ongoing contributions to
making the existing device support sustainable. Once the existing device support is
more sustainable, early research and development work for other devices can begin.
Once a device is deemed to be a worthwhile target, the project needs maintainers to
develop and maintain support for it including addressing device-specific issues that
are uncovered, which will include issues uncovered in the device support code by
GrapheneOS hardening features.
It's not really a matter of time but rather a need for community support for the
project increasing. As an open source project, the way to get something to happen in
GrapheneOS is to contribute to it, and this is particularly true for device support
since it's very self-contained and can be delegated to separate teams for each
device. If you want to see more devices supported sooner, you should get to work on
identifying good devices with full support for alternative operating systems with
verified boot, etc. and then start working on integrating and testing support.
It should also be clear that the expectation is for people to buy a device to run
GrapheneOS, rather than GrapheneOS supporting their existing devices. This will only
become more true if GrapheneOS is successful enough to accomplish the goal of having
devices produced based on an SoC reference design with minor improvements for privacy
and security. Broad device support is the opposite of what the project wants to
achieve in the long term.
GrapheneOS aims to provide reasonably private and secure devices. It cannot do that
once device support code like firmware, kernel and vendor code is no longer actively
maintained. Even if the community was prepared to take over maintenance of the open
source code and to replace the rest, firmware would present a major issue, and the
community has never been active or interested enough in device support to consider
attempting this. Unlike many other platforms, GrapheneOS has a much higher minimum
standard than simply having devices fully functional, as they also need to provide the
expected level of security. It would start to become realistic to provide
substantially longer device support once GrapheneOS controls the hardware and firmware
via custom hardware manufactured for it. Until then, the lifetime of devices will
remain based on manufacturer support. It's also important to keep in mind that phone
vendors claiming to provide longer support often aren't actually doing it and some
never even ship firmware updates when the hardware is still supported by the
vendors...
GrapheneOS also has high standards for the privacy and security properties of the
hardware and firmware, and these standards are regularly advancing. The rapid pace of
improvement has been slowing down, but each hardware generation still brings major
improvements. Over time, the older hardware starts to become a substantial liability
and holds back the project. It becomes complex to simply make statements about the
security of the project when exceptions for old devices need to be listed out. The
project ends up wanting to drop devices for this reason but has always kept them going
until the end-of-life date to provide more time for people to migrate.
The following devices are no longer supported:
- Pixel 2 XL (taimen)
- Pixel 2 (walleye)
- Pixel XL (marlin)
- Pixel (sailfish)
- Nexus 6P (angler)
- Nexus 5X (bullhead)
- Nexus 9 (flounder)
- Nexus 5 (hammerhead)
- Samsung Galaxy S4 (jflte)
GrapheneOS also used to provide official source-level support for the
following development boards but dropped support due to lack of community
interest and lack of hardware availability:
- HiKey 960 (hikey960)
- HiKey (hikey)
GrapheneOS uses an enhanced version of the modern filesystem-based disk
encryption implementation in the Android Open Source Project. The officially
supported devices have substantial hardware-based support for enhancing the
security of the encryption implementation. GrapheneOS has full support for the
hardware-based encryption features just as it does with other hardware-based
security features.
Firmware and OS partitions are identical copies of the images published in
the official releases. The authenticity and integrity of these partitions is
verified from a root of trust on every boot. No data is read from any of these
images without being cryptographically verified. Encryption is out of scope
due to the images being publicly available. Verified boot offers much stronger
security properties than disk encryption. Further details will be provided in
another section on verified boot in the future.
The data partition stores all of the persistent state for the operating
system. Full disk encryption is implemented via filesystem-based encryption
with metadata encryption. All data, file names and other metadata is always
stored encrypted. This is often referred to as file-based encryption but it
makes more sense to call it filesystem-based encryption. It's implemented by
the Linux kernel as part of the ext4 / f2fs implementation rather than running
a block-based encryption layer. The advantage of filesystem-based encryption
is the ability to use fine-grained keys rather than a single global key that's
always in memory once the device is booted.
Disk encryption keys are randomly generated with a high quality CSPRNG and
stored encrypted with a key encryption key. Key encryption keys are derived at
runtime and are never stored anywhere.
Sensitive data is stored in user profiles. User profiles each have their
own unique, randomly generated disk encryption key and their own unique key
encryption key is used to encrypt it. The owner profile is special and is used
to store sensitive system-wide operating system data. This is why the owner
profile needs to be logged in after a reboot before other user profiles can be
used. The owner profile does not have access to the data in other profiles.
Filesystem-based encryption is designed so that files can be deleted without
having the keys for their data and file names, which enables the owner profile
to delete other profiles without them being active.
GrapheneOS enables support for ending secondary user profile sessions after
logging into them. It adds an end session button to the lockscreen and in the
global action menu accessed by holding the power button. This fully purges the
encryption keys and puts the profiles back at rest. This can't be done for the
owner profile without rebooting due to it encrypting the sensitive system-wide
operating system data.
Using a secondary profile for regular usage allows you to make use of the
device without decrypting the data in your regular usage profile. It also
allows putting it at rest without rebooting the device. Even if you use the
same passphrase for multiple profiles, each of those profiles still ends up
with a unique key encryption key and a compromise of the OS while one of them
is active won't leak the passphrase. The advantage to using separate
passphrases is in case an attacker records you entering it.
File data is encrypted with AES-256-XTS and file names with AES-256-CTS. A
unique key is derived using HKDF-SHA512 for each regular file, directory and
symbolic link from the per-profile encryption keys, or the global encryption
key for non-sensitive data stored outside of profiles. The directory key is
used to encrypt the file names. GrapheneOS increases the file name padding
from 16 bytes to 32 bytes. AES-256-XTS with the global encryption key is also
used to encrypt filesystem metadata as a whole beyond the finer-grained file
name encryption.
The OS derives a password token from the profile's lock method credential
using scrypt. This is used as the main input for key derivation.
The OS stores a high entropy random value as the Weaver token on the secure
element (Titan M on Pixels) and uses it as another input for key derivation.
The Weaver token is stored alongside a Weaver key derived by the OS from the
password token. In order to retrieve the Weaver token, the secure element
requires the correct Weaver key. A secure internal timer is used to implement
hardware-based delays for each attempt at key derivation. It quickly ramps up
to 1 day delays before the next attempt. Weaver also provides reliable wiping
of data since the secure element can reliably wipe a Weaver slot. Deleting a
profile will wipe the corresponding Weaver slot and a factory reset of the
device wipes all of the Weaver slots. The secure element also provides insider
attack resistance preventing firmware updates before authenticating with the
owner profile.
Standard delays for encryption key derivation enforced by the secure
element:
- 0 to 4 failed attempts: no delay
- 5 failed attempts: 30 second delay
- 6 to 9 failed attempts: no delay
- 10 to 29 failed attempts: 30 second delay
- 30 to 139 failed attempts: 30 × 2⌊(n - 30) ÷ 10⌋
where n is the number of failed attempts. This means the delay
doubles after every 10 attempts. There's a 30 second delay after 30 failed
attempts, 60s after 40, 120s after 50, 240s after 60, 480s after 70, 960s
after 80, 1920s after 90, 3840s after 100, 7680s after 110, 15360s after
120 and 30720s after 130
- 140 or more failed attempts: 86400 second delay (1 day)
Invalid input outside the minimum or maximum length limits of the UI won't
trigger an attempt at authentication or key derivation.
GrapheneOS only officially supports devices with Weaver. The fallback
implementation for devices without it is out-of-scope for this FAQ.
The password token, Weaver token and other values like the OS verified boot
key are used by the TEE as inputs to a hardware-bound key derivation algorithm
provided by the SoC. The general concept is having the SoC perform hardware
accelerated key derivation using an algorithm like AES or HMAC keyed with a
hard-wired hardware key inaccessible to software or firmware. This is meant to
prevent offloading a brute force attack onto more powerful hardware without an
expensive process of extracting the hardware key from the SoC.
Many apps use the hardware keystore, their own encryption implementation or
a combination of those to provide an additional layer of encryption. As an
example, an app can use the hardware keystore to encrypt their data with a key
only available when the device is unlocked to keep their data at rest when the
profile is locked but not logged out. This is beyond the scope of this FAQ
section.
As of Android 10, only the configured default input method editor (your keyboard of
choice) and the currently focused app can access the clipboard. Apps without focus
cannot access the clipboard. This is a stricter restriction than preventing apps in
the background from accessing it, since an app in the foreground or a foreground
service cannot access it, only the foreground app that's currently focused. Clipboard
managers need to be implemented by the keyboard chosen as the default by the user.
GrapheneOS previously restricted background clipboard access as a much earlier and
slightly less strict implementation of this feature. It provided a toggle for users to
whitelist clipboard managers, which is no longer needed now that keyboards are
expected to provide it.
As of Android 12, the user is notified when an app reads clipboard content
which was set by a different app. This notice is enabled by default and can be
toggled under Settings ➔ Privacy ➔ Show clipboard access.
As of Android 10, apps cannot obtain permission to access non-resettable hardware
identifiers such as the serial number, MAC addresses, IMEIs/MEIDs, SIM card serial
numbers and subscriber IDs. Only privileged apps included in the base system with
READ_PRIVILEGED_PHONE_STATE
whitelisted can access these hardware
identifiers. Apps targeting Android 10 will receive a SecurityException
and older apps will receive an empty value for compatibility.
Since these restrictions became standard, GrapheneOS only makes a small change to
remove a legacy form of access to the serial number by legacy apps, which was still
around for compatibility. It used to need more extensive changes such as disallowing
access to the serial number but those restrictions are now standard.
Apps can determine the model of the device (such as it being a Pixel 5) either
directly or indirectly through the properties of the hardware and software. There
isn't a way to avoid this short of the OS supporting running apps in a virtual machine
with limited functionality and hardware acceleration. Hiding the CPU/SoC model would
require not even using basic hardware virtualization support and these things could
probably still be detected via performance measurements.
In addition to not having a way to identify the hardware, apps cannot directly
identify the installation of the OS on the hardware. Apps only have a small portion of
the OS configuration exposed to them and there is not much for device owners to change
which could identify their installation. Apps can detect that they're being run on
GrapheneOS via the privacy and security features placing further restrictions on them
and hardening them against further exploitation. Apps can identify their own app
installation via their app data and can directly (until that's removed) or indirectly
identify a profile. Profiles should be used when separate identities are desired.
Profiles can be used as temporary ephemeral identities by creating them for a specific
need and then deleting them. The rest of this answer only provides more technical
details, so you can stop reading here if you only want an overview and actionable
advice (i.e. use profiles as identities not inherently tied to each other).
Examples of the global OS configuration available to apps are configured
locale, time zone, network country code, whether the dark theme is enabled and
other similar global settings. Similar to extension and browser configuration
/ state being fingerprinted by web sites, an app could use a combination of
these things in an attempt to identify the installation. All of these things
vary at runtime and can be changed, but some are fairly unlikely to change in
practice after the initial setup of the device such as the ones listed above.
GrapheneOS will likely add further restrictions in this area and a couple
toggles for certain cases like time zones to use a standard value instead.
Apps can generate their own 128-bit or larger random value and use that as an
identifier for the app installation. Apps can create data in their app-specific
external storage directory by default without needing permission, and in the legacy
storage model before API 29 that data persists after the app is uninstalled, so it can
be used to store an ID that persists through the app being uninstalled and
reinstalled. However, external storage is under control of the user and the user can
delete this data at any time, including after uninstalling the app. In the modern
storage model, this data is automatically removed when the app is uninstalled.
GrapheneOS includes Seedvault as an OS backup service which must be explicitly
enabled, and it has the option to automatically restore app data when an app is
reinstalled, so it wouldn't lose track of it being the same profile.
The ANDROID_ID
string is a 64-bit random number, unique to each
combination of profile and app signing key. The 64-bit limitation means it isn't
particularly useful due to the possibility of collisions. It's tied to the lifetime of
profiles and does not persist through profile deletion or a factory reset. This is
comparable to an app targeting the legacy storage model storing a 64-bit random value
in the app-specific external storage directory. In the future, GrapheneOS will likely
change this to be tied to the lifetime of app installations rather than profiles. An
app could still track the identity of the profile through data you give it access to or
via data another app chooses to share with them.
The advertising ID is a Google Play services feature not included in the baseline
Android API, so it isn't an API included in GrapheneOS. The advertising ID is unique
to each profile. It isn't unique to each app signing key like ANDROID_ID
,
but that makes little difference since apps within the same profile can communicate
with each other with mutual consent. It's comparable to ANDROID_ID
but
provides an 128-bit value so it provides a strong cryptographic guarantee against
collisions, although a device messing with apps could set it to the same value used in
another profile. The advertising ID is exposed via the Settings app and can be reset
to a new random value, unlike ANDROID_ID
which remains the same for the
lifetime of the profile, but apps can tie it the previous ID since they can detect
that it changed via their own ID in their app data.
Apps do not have access to user data by default and cannot ever access the data of
other apps without those apps going out of the way to share it with them. If apps are
granted read access to user data like media or contacts, they could use it to identify
the profile. If apps are granted write access to user data, they could tag it to keep
track of the profile. Apps previously had little reason to do things like this because
they were able to persist data through an uninstall and reinstallation by default. The
modern storage model means they need to request access to user data to do this. The
existence of ANDROID_ID
means they don't yet need to bother with that but
that will change on GrapheneOS and will likely change for baseline Android too.
However, profiles are the only way to provide a strong assurance of separate
identities since the application model of the OS is designed to support communication
between apps within the same profile, but never between them.
GrapheneOS always considers networks to be hostile and avoids placing trust in
them. It leaves out various carrier apps included in the stock OS granting carriers
varying levels of administrative access beyond standard carrier configuration.
GrapheneOS also avoids trust in the cellular network in other ways including providing
a secure network time update implementation rather than trusting the cellular network
for this. Time is sensitive and can be used to bypass security checks depending on
certificate / key expiry.
Cellular networks use inherently insecure protocols and have many trusted parties.
Even if interception of the connection or some other man-in-the-middle attack along
the network is not currently occurring, the network is still untrustworthy and
information should not be sent unencrypted.
Authenticated transport encryption such as HTTPS for web sites avoids trusting the
cellular network. End-to-end encrypted protocols such as the Signal messaging protocol
also avoid trusting the servers. GrapheneOS uses authenticated encryption with modern
protocols, forward secrecy and strong cipher configurations for our services. We only
recommend apps taking a decent approach in this area.
Legacy calls and texts should be avoided as they're not secure and trust the
carrier / network along with having weak security against other parties. Trying to
detect some forms of interception rather than dealing with the root of the problem
(unencrypted communications / data transfer) would be foolish and doomed to
failure.
Connecting to your carrier's network inherently depends on you identifying yourself to
it and anyone able to obtain administrative access. Activating airplane mode will
fully disable the cellular radio transmit and receive capabilities, which will prevent
your phone from being reached from the cellular network and stop your carrier (and
anyone impersonating them to you) from tracking the device via the cellular radio. The
baseband implements other functionality such as Wi-Fi and GPS functionality, but each
of these components is separately sandboxed on the baseband and independent of each
other. Enabling airplane mode disables the cellular radio, but Wi-Fi can be re-enabled
and used without activating the cellular radio again. This allows using the device as
a Wi-Fi only device.
The LTE-only mode added by GrapheneOS is solely
intended for attack surface reduction. It should not be mistaken as a way to make
the cellular network into something that can be trusted.
GrapheneOS does not add gimmicks without a proper threat model and rationale. We
won't include flawed heuristics to guess when the cellular network should be trusted.
These kinds of features provide a false sense of security and encourage unwarranted
trust in cellular protocols and carrier networks as the default. These also trigger
false positives causing unnecessary concern and panic. Make good use of authenticated
encryption and airplane mode to avoid needing to depend on an insecure network.
Receiving a silent SMS is not a good indicator of being targeted by your cell
carrier, police or government because anyone on the cell network can send
them including yourself. Cellular triangulation will happen regardless of whether
or not SMS texts are being sent or received by the phone. Even if an SMS did serve a
useful purpose for tracking, a silent SMS would be little different than receiving
unsolicited spam. In fact, sending spam would be stealthier since it wouldn't trigger
alerts for silent SMS but rather would be ignored with the rest of the spam. Regardless,
sending texts or other data is not required or particularly useful to track devices
connected to a network for an adversary with the appropriate access.
See the usage guide section on Wi-Fi privacy.
GrapheneOS makes connections to the outside world to test connectivity, detect
captive portals and download updates. No data varying per user / installation / device
is sent in these connections. There aren't analytics / telemetry in GrapheneOS.
The expected default connections by GrapheneOS (including all base system apps) are
the following:
-
The GrapheneOS Updater app fetches update metadata from
https://releases.grapheneos.org/DEVICE-CHANNEL approximately once every four hours
when connected to a permitted network for updates.
Once an update is available, it tries to download
https://releases.grapheneos.org/DEVICE-incremental-OLD_VERSION-NEW_VERSION.zip
for a delta update, and then falls back to
https://releases.grapheneos.org/DEVICE-ota_update-NEW_VERSION.zip.
No query / data is sent to the server, so the only information leaked to it
are the variables in these 3 URLs (device, channel, current version) which is
necessary to obtain the update.
Users are in control of which types of networks the Updater app will use
and can disable the Updater app in extreme cases. It's strongly recommended to
leave it enabled to quickly receive security updates including updates outside
the regular monthly schedule.
The update client avoids trusting the data obtained from the update server
via signature verification with downgrade protection. Verified boot provides
another layer of signature verification with downgrade protection. GrapheneOS
servers do not have access to GrapheneOS signing keys.
See the usage guide's section on updates for
more information.
-
An HTTPS connection is made to https://time.grapheneos.org/ to update the
time from the date header field. This is a full replacement of Android's
standard network time update implementation, which uses the cellular network
when available with a fallback to SNTP when it's not available. Network time
updates are security sensitive since certificate validation depends on having
an accurate time, but the standard NTP / SNTP protocols used across most OSes
have no authentication.
We plan to offer a toggle to use the standard functionality instead of
HTTPS-based time updates in order to blend in with other devices.
Network time can be disabled with the toggle at Settings ➔ System ➔ Date
& time ➔ Set time automatically. Unlike AOSP or the stock OS on the
supported devices, GrapheneOS stops making network time connections when using
network time is disabled rather than just not setting the clock based on it.
The time zone is still obtained directly via the time zone provided by the
mobile network (NITZ) when available which you can also disable by the "Set
time zone automatically" toggle.
-
On devices with a Qualcomm baseband (which provides GPS), when location
functionality is enabled and being used,
GPS almanacs
are downloaded from https://xtrapath1.izatcloud.net/xtra3grc.bin,
https://xtrapath2.izatcloud.net/xtra3grc.bin or
https://xtrapath3.izatcloud.net/xtra3grc.bin which are currently (as of
September 2020) hosted via Amazon Web Services. GrapheneOS has modified all
references to these servers to use HTTPS rather than a mix of HTTP and HTTPS.
No query / data is sent to the server.
We plan to offer the option to download these files from the GrapheneOS
servers, but we'll retain the option to use the standard servers to blend in
with other devices.
-
Connectivity checks designed to mimic a web browser user agent are performed
by using HTTP and HTTPS to fetch standard URLs generating an HTTP 204 status
code. This is used to detect when internet connectivity is lost on a network,
which triggers fallback to other available networks if possible. These checks
are designed to detect and handle captive portals which substitute the
expected empty 204 response with their own web page.
The connectivity checks are done by performing an empty GET request to a
server returning an empty response with a 204 No Content response code. The
request uses a standard, frozen value for the user agent matching the same
value used by billions of other Android devices:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.32 Safari/537.36
No query / data is sent to the servers and the response is unused beyond
checking the response code.
Connectivity checks are performed for each network connection and
for VPN connections on top of those. This allows the OS to choose the
right underlying network for a VPN and to handle many types of captive
portals without the user turning off their VPN.
You can change the connectivity check URLs via the Settings ➔
Network & Internet ➔ Internet connectivity check setting.
At the moment, it can be toggled between the GrapheneOS servers
(default), the standard Google servers used by billions of other
Android devices or disabled.
By default, the GrapheneOS connectivity check servers are used via the
following URLs:
- HTTPS: https://connectivitycheck.grapheneos.network/generate_204
- HTTP: http://connectivitycheck.grapheneos.network/generate_204
- HTTP fallback: http://grapheneos.online/gen_204
- HTTP other fallback: http://grapheneos.online/generate_204
Changing this to the Standard (Google) mode will use the same URLs
used by AOSP and the stock OS along with the vast majority of other
devices, blending in with billions of other Android devices both with
and without Play services:
- HTTPS: https://www.google.com/generate_204
- HTTP: http://connectivitycheck.gstatic.com/generate_204
- HTTP fallback: http://www.google.com/gen_204
- HTTP other fallback: http://play.googleapis.com/generate_204
GrapheneOS also adds the ability to fully disable the connectivity
checks. This results in the OS no longer handling captive portals
itself, not falling back to other networks when some don't have
internet access and not being able to delay scheduled jobs depending
on internet access until it becomes available.
-
DNS connectivity and functionality tests
-
DNS resolution for other connections
Vanadium does not make connections not requested by the app as part of providing
the WebView implementation in the OS. If you choose to use it as your browser, it
performs similar connections as the ones performed by the OS above. It does not send
any identifying information to servers, etc. but rather fetches some static assets
like dictionaries when triggered by usage of the app. We're working on eliminating
everything unnecessary and making our servers the default for handling anything that
cannot simply be shipped with Vanadium for one reason or another such as requiring
quicker updates.
GrapheneOS services follow the EFF's
privacy-friendly Do Not Track (DNT) policy for all users of our publicly available
services, not just those opting out of tracking via Do Not Track. Our policy is the
same with "DNT User" redefined as "user" to cover any user. This serves as a standard
privacy policy across all of our public services:
- attestation.app
- grapheneos.network
- grapheneos.org
- releases.grapheneos.org
- time.grapheneos.org
Our implementation of the policy primarily consists of making sure our servers only
retain logs for 10 days. In practice, we follow much stricter privacy guidelines than
than the rules laid out in the EFF policy. However, we don't want to define our own
complex, ad-hoc privacy policy rather than reusing a sensible one with serious thought
put into it by experts.
Our mail server (mail.grapheneos.org) isn't offered as a public service and doesn't
have a privacy policy since it's only used internally by GrapheneOS developers.
The OS uses the network-provided DNS servers by default. Typically, dynamic
IP configuration is used to auto-configure the client on the network. IPv4 DNS
servers are obtained via DHCP and IPv6 DNS servers are obtained via RDNSS. For
a static IP configuration, the DNS servers are manually configured as part of
the static configuration.
A VPN provides a network layered on top of the underlying networks and the
OS uses the VPN-provided DNS servers for everything beyond resolving the IP
address of the VPN and performing network connectivity checks on each of the
underlying networks in addition to the VPN itself.
Using the network-provided DNS servers is the best way to blend in with
other users. Network and web sites can fingerprint and track users based on a
non-default DNS configuration. Our recommendation for general purpose usage is
to use the network-provided DNS servers.
In some broken or unusual network environments, the network could fail to
provide DNS servers as part of dynamic IP configuration. The OS has high
availability fallback DNS servers to handle this case. A network can fail to
provide DNS servers in order to fingerprint clients based on what they use as
the fallback so it's important for it to be consistent across each install.
GrapheneOS replaces Google Public DNS with
Cloudflare
DNS for the fallback DNS servers due to the superior privacy policy and
widespread usage including as the fallback DNS servers in other Android-based
operating systems. We're considering hosting our own servers and offering a
toggle for using the standard (Google) servers to blend in with other devices
similarly to how we handle the internet connectivity checks.
It isn't possible to directly override the DNS servers provided by the network via
DHCP. Instead, use the Private DNS feature in Settings ➔ Network & Internet ➔
Private DNS to set the hostname of a DNS-over-TLS server. It needs to have
a valid certificate such as a free certificate from Let's Encrypt. The OS will look up
the Private DNS hostname via the network provided DNS servers and will then force all
other DNS requests through the Private DNS server. Unlike an option to override the
network-provided DNS servers, this prevents the network from monitoring or tampering
with DNS requests/responses.
As an example, set the hostname to one.one.one.one
for Cloudflare DNS.
There are various other mainstream DNS-over-TLS options available including Quad9,
Google and AdGuard.
Configuring a static IP address for a network requires entering DNS servers
manually, but you should still use the Private DNS feature with it, and you shouldn't
misuse the static IP address option just to override the DNS servers.
VPN service apps can also provide their own DNS implementation and/or servers,
including an alternate implementation of encrypted DNS. Private DNS takes precedence
over VPN-provided DNS, since it's just the network-provided DNS.
Apps and web sites can detect the configured DNS servers by generating random
subdomains resolved by querying their authoritative DNS server. This can be used as
part of fingerprinting users. If you're using a VPN, you should consider using the
standard DNS service provided by the VPN service to avoid standing out from other
users.
By default, in the automatic mode, the Private DNS feature provides opportunistic
encryption by using DNS-over-TLS when supported by the DNS server IP addresses
provided by the network (DHCP) or the static IP configuration. Opportunistic
encryption provides protection against a passive listener, not an active attacker,
since they can force falling back to unencrypted DNS by blocking DNS-over-TLS. In the
automatic mode, certificate validation is not enforced, as it would provide no
additional security and would reduce the availability of opportunistic encryption.
When Private DNS is explicitly enabled, it uses authenticated encryption without a
fallback. The authentication is performed based on the hostname of the server, so it
isn't possible to provide an IP address. The OS will look up the hostname of the Private
DNS server via unencrypted DNS and then force all other DNS lookups via DNS-over-TLS
with the identity of the server authenticated as part of providing authenticated
encryption.
No, it only provides privacy for DNS resolution. Even authenticating DNS results
with DNSSEC does not protect other connections, unless the DNS records are part of the
system used to provide authenticated encryption, and DNS-over-TLS is not a substitute
for DNSSEC. If connections have authenticated encryption, they're secure even if DNS
resolution is hijacked by an attacker. If connections do not have authenticated
encryption, an attacker can listen in and tamper with them without hijacking DNS.
There are other ways to perform a MITM attack than DNS hijacking and internet routing
is fundamentally insecure. DNS-over-TLS may make a MITM harder for some attackers, but
don't count on it at all.
Private DNS only encrypts DNS, and an adversary monitoring connections can still
see the IP address at the other end of those connections. Many domains resolve to
ambiguous IP addresses, so encrypted DNS is part of what's required to take away a lot
of the information leaked to adversaries. However, TLS currently leaks domains via
SNI, so encrypted DNS is not yet accomplishing much. It's a forward looking feature
that will become more useful in the future. Using it is recommended, but it's not an
alternative to using Tor or a VPN.
VPNs can be configured under Settings ➔ Network & Internet ➔ VPN.
Support for the following protocols is included: IKEv2/IPSec MSCHAPv2,
IKEv2/IPSec PSK and IKEv2/IPSec RSA. Apps can also provide userspace VPN
implementations and the following open source apps are recommended: Orbot
(Tor), WireGuard and OpenVPN for Android.
VPN configurations created with the built-in support can be set as the
always-on VPN in the configuration panel. This will keep the VPN running,
reconnecting as necessary and will force all connections through them. An app
providing a VPN service can also be set as the always-on VPN via the entry in
the Settings page. For app-based VPN implementations, there's also an
additional "Block connections without VPN" toggle which is needed to prevent
leaks when the app's VPN service isn't running.
Apps cannot monitor network connections unless they're made into the active VPN
service by the user. Apps cannot normally access network stats and cannot directly
request access to them. However, app-based stats can be explicitly granted by users as
part of access to app usage stats in Settings ➔ Apps ➔ Special app access ➔ Usage
access.
This was previously part of the GrapheneOS privacy improvements, but became a
standard Android feature with Android 10.
Yes, GrapheneOS inherits the deeply integrated firewall from the Android Open
Source Project, which is used to implement portions of the security model and various
other features. The GrapheneOS project historically made various improvements to the
firewall but over time most of these changes have been integrated upstream or became
irrelevant.
GrapheneOS adds a user-facing Network permission toggle providing a robust way to
deny both direct and indirect network access to applications. It builds upon the
standard non-user-facing INTERNET permission, so it's already fully adopted by the app
ecosystem. Revoking the permission denies indirect access via OS components and apps
enforcing the INTERNET permission, such as DownloadManager. Direct access is denied
by blocking low-level network socket access.
The recommended approach to system-wide ad-blocking is setting up
domain-based ad-blocking as part of DNS resolution. You can do this by
choosing a Private DNS (DNS-over-TLS) server with
support for blocking ad domains. As an example, AdGuard DNS can be used by
setting dns.adguard.com
as the Private DNS domain. This feature
used to be included by the project many years ago, but it needs to be
reimplemented, and it's a low priority feature depending on contributors
stepping up to work on it.
Apps and web sites can detect that ad-blocking is being used and can
determine what's being blocked. This can be used as part of fingerprinting
users. Using a widely used service like AdGuard with a standard block list is
much less of an issue than a custom set of subscriptions / rules, but it still
stands out compared to the default of not doing it.
Content filtering apps are fully compatible with GrapheneOS, but they have serious
drawbacks and are not recommended. These apps use the VPN service feature to route
traffic through themselves to perform filtering.
The approach of intercepting traffic is inherently incompatible with encryption
from the client to the server. The AdGuard app works around encryption by supporting
optional
HTTPS interception by
having the user trust a local certificate authority, which is a security risk and
weakens HTTPS security even if their implementation is flawless (which they openly
acknowledge in their documentation, although it understates the risks). It also can't
intercept connections using certificate pinning, with the exception of browsers which
go out of the way to allow overriding pinning with locally added certificate
authorities. Many of these apps only provide domain-based filtering, unlike the deeper
filtering by AdGuard, but they're still impacted by encryption due to Private DNS
(DNS-over-TLS) and require disabling the feature. They could provide their own
DNS-over-TLS resolver to avoid losing the feature, but few of the developers care
enough to do that.
Using the VPN service to provide something other than a VPN also means that these
apps need to provide an actual VPN implementation or a way to forward to apps
providing one, and very few have bothered to implement this. NetGuard is an one
example implementing SOCKS5 forwarding, which can be used to forward to apps like
Orbot (Tor).
Yes, the baseband is isolated on all of the officially supported devices. Memory
access is partitioned by the IOMMU and limited to internal memory and memory shared
by the driver implementations. The baseband on the officially supported devices with a
Qualcomm SoC implements Wi-Fi and Bluetooth as internal sandboxed processes rather
than having a separate baseband for those like earlier devices.
Earlier generation devices we used to support prior to Pixels had Wi-Fi + Bluetooth
implemented on a separate SoC. This was not properly contained by the stock OS and we
put substantial work into addressing that problem. However, that work has been
obsoleted now that Wi-Fi and Bluetooth are provided by the SoC on the officially
supported devices.
A component being on a separate chip is orthogonal to whether it's isolated. In
order to be isolated, the drivers need to treat it as untrusted. If it has DMA access
that needs to be contained via IOMMU and the driver needs to treat the shared memory
as untrusted, as it would data received another way. There's a lot of attack surface
between the baseband and the kernel/userspace software stack connected to it. OS
security is very relevant to containing hardware components including the radios and
the vast majority of the attack surface is in software. The OS relies upon the
hardware and firmware to be able to contain components but ends up being primarily
responsible for it due to control over the configuration of shared memory and the
complexity of the interface and the OS side implementation.
The mobile Atheros Wi-Fi driver/firmware is primarily a SoftMAC implementation with
the vast majority of the complexity in the driver rather than the firmware. The fully
functional driver is massive and the firmware is quite small. Unfortunately, since the
Linux kernel is monolithic and has no internal security boundaries, the attack surface
is problematic and a HardMAC implementation with most complexity in the isolated
firmware could be better than the status quo. An isolated driver would be ideal.


Overview
Cuppa Angular Fan Menu is an `angular 1 directive` for cool menu componet for web and mobile, developed using `angularJS`, `CSS3`, `HTML5`.
Features
- Highly Configurable directive properties and methods
- Draggable
- Touch enabled
- Cool fan effect transitions
Getting Started
Installation
-
Install with npm:
npm install cuppa-angular-datepicker
OR
-
Clone
this repository and setup with the below instructions.
Basic Usage
Include circularmenu-directive.js
directive at the bottom of your page or in the <head>
section.
<script src="circularmenu-directive.js" type="text/javascript"></script>
Initialize the directive by adding the directive name as a dependency to your app controller and declare the config object and menu items model as follows
angular
.module('demoApp', ['circularMenu-directive'])
.controller('demoController',function($scope){
$scope.menuConfig = {
"buttonWidth": 60,
"menuRadius": 160,
"color": "#ff7f7f",
"offset":25,
"textColor": "#ffffff",
"showIcons":false,
"gutter": {
"top": 130,
"right": 30,
"bottom": 30,
"left": 30
},
"angles": {
"topLeft": 0,
"topRight": 90,
"bottomRight": 180,
"bottomLeft": 270
}
};
$scope.menuItems = [{
"title": "iPad",
"color": "#ea2a29",
"rotate": 0,
"show": 0,
"titleColor": "#fff",
"icon":{"color":"#fff","name":"fa fa-tablet","size": 35}
}, {
"title": "iMac",
"color": "#f16729",
"rotate": 0,
"show": 0,
"titleColor": "#fff",
"icon":{"color":"#fff","name":"fa fa-laptop","size": 30}
}, {
"title": "iPhone",
"color": "#f89322",
"rotate": 0,
"show": 0,
"titleColor": "#fff",
"icon":{"color":"#fff","name":"fa fa-mobile","size": 30}
}, {
"title": "iWatch",
"color": "#ffcf14",
"rotate": 0,
"show": 0,
"titleColor": "#fff",
"icon":{"color":"#fff","name":"fa fa-clock-o","size": 30}
}];
})
Add the directive attribute and the corresponding config attributes to the html template or page of your app.
<div drag-circular-menu
angle="30"
placement="topLeft"
button-config="menuConfig"
menu-items="menuItems"
default-open="true"
onwing-click="onWingClick1(wing)">
</div>
API Documentation
Directive Configuration
Once the directive attribute is added to the element, it can be configured with the following configuration attributes.
| Attribute | Type | Required | Default | Description |
|---|---|---|---|---|
drag-circular-menu |
attribute | YES | '' |
Directive attribute to be defined on an element to initialize. |
angle |
string | YES | 30 |
The angle at which the menu wings open when clicked. |
placement |
string | YES | topLeft |
Position at the which the menu appears on load. Possible values are topLeft , topRight , bottomLeft ,bottomRight |
button-config |
Object | YES | None |
Menu button configuration Object. Set of button properties to be defined. Refer to Config Object Section below for details. |
menu-items |
Array [Object] | YES | none |
Array of menu item objects. Each menu is an object. Refer to the Data Array - Menu Item Object Properties below for details. |
default-open |
Boolean | YES | '' |
Open menu automatically on load. |
onwing-click |
Method | YES | '' |
Callback on menu item wing cicked. |
Config Object
| Property | Type | Required | Description |
|---|---|---|---|
buttonWidth |
Number | YES | Width of the menu button. |
menuRadius |
Number | YES | The radius of the menu wings from the center of the button. |
color |
Hex Code | YES | Button color. Hex color code. |
offset |
Number | YES | The gap between the menu button and the menu item wings. |
textColor |
Hex Code | YES | Button text color. Hex color code. |
showIcons |
Boolean | YES | To show or hide icons along with the text in menu item wing. |
gutter |
Object | YES | The space between the menu and the bounderies of the page window. The object can have four properties left , right , top , bottom with values to be defined in Number |
angles |
Object | YES | The angle at which the menu opens when clicked. It can be configured to open at different angles when placed at different places. The value of the angle can be a number between 0 -360 |
Data Array
-
menuItems - Arryay [menuObject]
-
menuObject {} properties
| Property | Type | Required | Description |
|---|---|---|---|
title |
String | YES | Title of the menu item. |
color |
Hex Code | YES | Background color of the wing. |
rotate |
Number | YES | Initial angle of the wing. Default to Zero. |
show |
Boolean | YES | Show or hide the wing. |
titleColor |
Hex Code | YES | Text color of the title. |
icon |
Object | YES | Icon object properties. {“color”:”#fff”,”name”:”fa fa-tablet”,”size”: 35} |
Build & development
If you want develope and build on this component, there are some quick steps for that.
clone
the git repository to your local- run
npm install
to download and install all the development dependencies. - run
bowerinstall
to download all the front end developemnt dependencies. - run
grunt serve
to start the server and get the app up and running. It automatically opens a browser window instance, with the app runnning. - run
grunt build
to generate production ready code in dist folder.
Licence
This project is licensed under the MIT license. See the LICENSE file for more info.
–
The MIT License (MIT) Copyright (c) 2016 Cuppa Labs
Credits
Thanks to Font Awesome the library.
Pradeep Terli
Web UI Developer, Blogger, Thinker , Entrepreneur. Loves to explore technology with focus on web technologies.


class: center, middle, inverse, title-slide #
Session 1:
Overview of Pharmacokinetic Models and Computational Toolkits ##
### .font125[Nan-Hung Hsieh, PhD] Postdoc @ Texas A&M Superfund Decision Science Core ### 12/09/2019 --- background-image: url(https://github.com/nanhung/pksensi/raw/master/man/figures/logo.png) background-size: 150px background-position: 95% 95% # About Me ### MS in Safety, Health and Environmental Engineering @ National United University ### PhD in Bioenvironmental Systems Engineering @ National Taiwan University .font125[ - Research Associate @ Institute of Labor, Occupational Safety And Health, Ministry of Labor - Postdoctoral Research Associate @ Texas A&M University -  Associate Toxicologist @ California Environmental Protection Agency
 **My Research:** .bolder[Computational Toxicology] & .bolder[Risk Assessment] **Interest:** .bolder[Software Development] ] --- # Content ## 1 Basic Pharmacokinetics Concepts ## 2 Pharmacokinetic Models ## 3 Computational Toolkits ## 4 Hands-on Exercise --- class:middle, center .font300[ # Basic Pharmacokinetics Concepts ] --- class:middle, center .font300[ Why We Need to Do **Computational Modeling** in Toxicology? ] -- .font300[.bolder["Prediction"]] --- # Pharmacokinetics (PK) / Toxiccokinetics (TK) .font125[ - The study of the movement of chemicals in and out of the body (“what the body does to the chemical”) - **ADME** process .center[ **A**bsorption - How will it get in? **D**istribution - Which tissue organ it will go? **M**etabolism - How is it broken down and transformation? **E**xcretion - How it leave the body? ] - Kinetics: rates of change - PK is focus on .bolder[TIME (t)] and .bolder[CONCENTRATION (C)] ] --- # Pharmacokinetics / Pharmacodynamics .large[ Pharmacokinetics is the study of the fate of chemical in a living organism through .bolder[ADME] process (**absorption**, **distribution**, **metabolism**, and **elimination**). ] .center[![](https://media.springernature.com/original/springer-static/image/art%3A10.1007%2Fs00535-015-1061-4/MediaObjects/535_2015_1061_Fig1_HTML.gif) .font125[ **"PK"** focus on .bolder[DOSE] to .bolder[CONCENTRATION] / **"PD"** focus on .bolder[Concentration] to .bolder[Response] ] ] --- # Pharmacokinetics profile .pull-left[![](https://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Linear_PK_Example.png/1280px-Linear_PK_Example.png)] .pull-right[ `\(t\)`: Time `\(C\)`: Concentration `\(C_{max}\)`: The peak concentration `\(t_{max}\)`: Time to reach `\(C_{max}\)` `\(t_{1/2}\)`: Elimination half- life `\(AUC\)`: Area under the curve
 During the continous dose administered `\(C_{ss}\)`: The averaged concentration `\(C_{min}\)`: The lowest concentration that a drug reaches ] .footnote[https://en.wikipedia.org/wiki/Pharmacokinetics] --- # Absorption ### Movement of chemical into the body .font125[ - **Rate of absorption** (how quickly does it absorb?) - **Fraction of absorption** (how percentage does it absorb?) ] .bolder[Bioavailability] ia a key factor for substance becomes available to the target tissue after administration.
 ### Exposure routes .font125[ - Inhalation – alveolar gas exchange - Oral – gut absorption - Dermal – permeation through skin - Intravenous ] .bolder[Different exposure route can related to different PK profile] --- # Absorption & Distribution .center[ ![:scale 70%](https://erj.ersjournals.com/content/erj/28/5/1042/F1.large.jpg) ] .footnote[https://doi.org/10.1183/09031936.00074905] --- # Distribution .font125[ - Transfer of the chemical between general circulation and tissues - Important toxicologically because tissue concentration drives toxicity - Factors affecting tissue distribution - **Blood flow** to tissues - Tissue distribution (For chemicals that rapidly diffuse through membranes) - Assume rapid equilibrium between blood and tissue - Ratio is the tissue:blood **partition coefficient** (Partition coefficient = Concentration in tissue / Concentration in blood) - Delivery to tissue limited by blood flow (“flow-limited”). ] --- background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Michaelis_Menten_curve_2.svg/1920px-Michaelis_Menten_curve_2.svg.png) background-size: 400px background-position: 95% 95% # Metabolism/transformation - Enzyme systems, etc. covered in separate class. - Phase I – conversion to more polar metabolite, e.g., oxidation by cytochrome P450 - Phase II – conjugation with an endogenous substrate to increase solubility, e.g., GSH conjugation, glucuronidation - Key issues relevant to risk assessment - What are the metabolites? - In what tissues does metabolism occur? - What are the rates of metabolism? - What is known about interspecies and intraspecies differences? - **Metabolism process** - **First order kinetics** (linear; constant) - **Michaelis-Menten Kinetics** (Non-linear; concentration dependent) --- # Metabolism - Acetaminophen .center[![](https://i.ibb.co/M1kNrnt/13318-2015-253-Fig2-HTML-gif.png)] .font125[ - Acetaminophen (APAP) is a widely used pain reliver and fever reducer. - The therapeutic index (ratio of toxic to therapeutic doses) is unusually small. - .bolder[Phase I] (APAP to NAPQI) is toxicity pathway at high dose. - .bolder[Phase II] (APAP to APAP-Glucuronidation & APAP to APAP-Sulfation) is major pathways at therapeutic dose. ] --- # Trichloroethylene GSH conjugation pathway .pull-left[ - Initial conjugation with GSH - Subsequent biotransformation occurs in multiple tissues via both Phase I and Phase II metabolism ![](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4254735/bin/nihms-593254-f0003.jpg) ] .pull-right[ ![:scale 60%](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4254735/bin/nihms-593254-f0002.jpg) ] .footnote[ Lash, L.H., et al. 2014. [Trichloroethylene biotransformation and its role in mutagenicity](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4254735/). ] --- # Excretion ## Excretion is the removal from the body .font125[ - Urine - Exhalation - Feces - Minor pathways: sweat, saliva, milk ]
 .bolder[Excretion and elimination are often confused] - Excretion is reserved for exiting the body - Elimination is the disappearance of a chemical, including both excretion and metabolism --- # Elimination kinetics .pull-left[ ### Zero-order kinetics The elimination is **independent** with internal chemical dose
 ### First-order kinetics The elimination is **dependent** with internal chemical dose ] .pull-right[ ![](https://i.ibb.co/dBqNkC4/6364e7765a1b6c1f0083edea2c5283ed.png) ] .footnote[ https://forum.facmedicine.com/threads/elimination-kinetics-first-and-zero-order-kinetics.25353/ ] --- # Impact of TK on risk assessment .font150[ - Concentration **prediction** - Identifying the toxicologically active agent(s) - Providing a basis for **extrapolating** from experimental studies to humans - Characterizing how humans may vary in their response to exposure due to differences in internal dose ] --- class:middle, center .font300[ # Pharmacokinetic Models ] --- background-image: url(https://wol-prod-cdn.literatumonline.com/cms/attachment/87cce77b-8dd4-4928-869f-b230e0cffcc4/psp412134-fig-0003-m.jpg) background-size: 700px background-position: 90% 90% # Why Pharmacokinetic Modeling - **Pharmaceutical research** - **Drug development** - **Health risk assessment** . . . --- # High Throughput Risk Prioritization According to Toxic Substances Control Act (TSCA), to address thousands of chemicals, we need to use **new approach methodologies (NAMs)** to prioritize the existing and new chemicals for testing. .pull-left[ ## Main components ### 1. High throughput hazard characterization ### 2. High throughput exposure forecasts ### 3. High throughput **toxicokinetics** ] .pull-right[ ![:scale 75%](https://i.ibb.co/ZW5Nq1S/Screenshot-from-2019-12-04-11-30-13.png) ] .footnote[source: [USEPA](https://cfpub.epa.gov/si/si_public_record_report.cfm?Lab=NCCT&dirEntryId=340966)] --- # Pharmacokinetic Model ### What information we want to know through .bolder["prediction"]? .pull-left[ # Time .font150[ - When the chemical can reach the peak concentration in the body? - How long it stay in the body? ] ] .pull-right[ # Concentration .font150[ - What is the peak concentration? - What is the average concentration? ] ] --- # Mathematical method ## How to conduct simulation? .font125[ .pull-left[ **Numerical** - Use the differential equation containing one or more functions of one independent variable and the derivatives of those functions. .font150[ `$$\frac{dA}{dt}=-k_{e} \cdot A$$` ] ] .pull-right[ **Analytical** - The simple equation with a independent variable of time
 .font150[ `$$A(t) = A_0 \cdot e^{-k_{e} \cdot t}$$` ] ] ] .footnote[ `\(A\)`: Amount in body (mass); `\(A_0\)` initial amount (mass); `\(t\)`: time; `\(k_e\)`: Elimination rate constant (/time) ] ??? The basic meaning of elimination rate is that the decreasing speed is the propotion of current concentration. --- background-image: url(https://i.ibb.co/t2hLp0m/pk1cpt.jpghttps://i.ibb.co/t2hLp0m/pk1cpt.jpg) background-size: 200px background-position: 40% 80% # Intravenous administration .pull-left[ .font150[ **Numerical** `\(\frac{dA}{dt}=-k_{e} \cdot A\)` **Analytical** `\(A_t = A_0 \cdot e^{-k_{e} \cdot t}\)` ] ] .pull-right[ .code75[ ```r A_0 <- 10 t <- c(0,1,2,4,8,10) k_e <- 0.5 A_t <- A_0*exp(-k_e*t) plot(t, A_t, type = "b") ``` ![](191209_srp1_files/figure-html/unnamed-chunk-2-1.svg) ] ] --- # Oral administration .pull-left[
 ![](https://i.ibb.co/zQ4t9Wn/pk1cpt.jpg) `$$C(t) = \frac{F\cdot D \cdot ka}{V(k_a - k_e)}\cdot(\mathrm{e}^{-k_et}-\mathrm{e}^{-k_a{t}})$$` `\(D\)`: Dose (mass) `\(F\)`: Bioavailability (-) `\(K_a\)` Absorption rate constant (/time) `\(k_e\)` Elimination rate constant (/time) `\(V\)`: Distribution Volume (Vol) ] .pull-right[ ![](191209_srp1_files/figure-html/unnamed-chunk-4-1.svg) ] --- # Empirical compartmental models .pull-left[ ## Advantages - Can continue adding compartments to fit more complex concentration-time profiles. - Can provide useful descriptions of the data. ] .pull-right[ ## Disadvantages - Cannot interpret compartments biologically. - Many A,D,M, and E processes are interconnected. - Cannot make predictions beyond the experiment being described. - Different tissues - Different exposure routes or conditions - Different species - Different individuals - Cannot incorporate everything else we know about biology! ] --- background-image: url(https://ars.els-cdn.com/content/image/1-s2.0-S0300483X18301781-gr2_lrg.jpg) background-size: 400px background-position: 95% 80% ## Example pf empirical compartmental models Luo, Y.S., Hsieh, N.H., Soldatow, V.Y., Chiu, W.A. and Rusyn, I., 2018. [Comparative Analysis of Metabolism of Trichloroethylene and Tetrachloroethylene among Mouse Tissues and Strains](https://doi.org/10.1016/j.tox.2018.07.012). Toxicology, 409, pp.33-43.
 ![:scale 62%](https://ars.els-cdn.com/content/image/1-s2.0-S0300483X18301781-gr1.jpg) --- # Physiological-Based Pharmacokinetic (PBPK) Mathematically transcribing .bolder[anatomical, physiological, physical, and chemical] descriptions of the phenomena involved in the complex .bolder[ADME] processes. .center[![:scale 60%](http://pharmguse.net/pkdm/pbpm.jpg)] --- # Why PBPK models? - There are some processes that empirical models have difficulty simulating – such as inhalation exposures. - We know a lot about the physiology/anatomy of the organisms we study and want to protect. - Organ/tissue sizes - Connections between organs/tissues - Blood flow rates - Ventilation rates - Metabolizing enzymes - Etc… By developing a model, we can incorporate that information to help us make inferences beyond the experimental data at hand. --- # Building a PBPK model - Decide on what compartments are needed - Target vs. non-target tissues - Tissues with in vivo vs. in vitro vs. no data - Exposure routes - Specify the (interrelated) equations for each compartment - Specify parameter values - Physiological/anatomical parameters - Chemical-specific parameters - Set up the inputs (doses, exposure concentrations, etc.) and outputs (blood, tissue, exhaled breath concentrations). - Solve using numerical differential equation solver and compare with data
 .bolder[Iteration may be needed for refining model and/or conducting additional experiments] --- background-image: url(https://i.ibb.co/5FfRyqT/IJN-86785-F01.png) background-size: 550px background-position: 88% 50% class: hide-logo .pull-left[ ## PBPK Workflow **Model Construction** - What type of data we have? - .bolder[A]: Input routes - .bolder[D]: Blood and other tissues - .bolder[M]: Metabolism - .bolder[E]: Urine or feces **Parameter Estimates** - Do we have any prior information? - Physiological parameter - Chemical-specific parameter **PBPK modeling** ] .footnote[ Chen et al. (2015) [Physiologically based pharmacokinetic modeling of zinc oxide nanoparticles and zinc nitrate in mice.](https://doi.org/10.2147/IJN.S86785) ] --- # Compartmental equations - Flow in and out of “storage” compartments involve only blood flow - Key parameters/variables `\(Q_i\)` = tissue blood flow `\(P_i\)` = tissue-blood partition coefficient `\(V_i\)` = volume of tissue `\(C_a\)` = arterial blood concentration `\(CV_i\)` = venous blood concentration leaving tissue `\(A_i\)` = amount in tissue `\(C_i\)` = concentration in tissue --- class: hide-logo .pull-left[ ![:scale 75%](https://www.dovepress.com/cr_data/article_fulltext/s86000/86785/img/IJN-86785-F02.png) ] .pull-right[ ![:scale 95%](https://www.dovepress.com/cr_data/article_fulltext/s86000/86785/img/IJN-86785-T02.png) ] --- # Basic transport equations The model equations follow the principles of mass transport, fluid dynamics, and biochemistry in order to simulate the fate of a substance in the body. rate in `\(= Q_iC_{art}\)` & rate out `\(= Q_iC_{VT} = Q_i \cdot C_i/P_i\)` (Unit: mass/time) Change in amount = rate in – rate out .font125[ `$$\frac{d A_{i}}{d t}=Q_{i}\left(C_{a r t}-\frac{A_{i}}{P_{i} V_{i}}\right)$$` or `$$\frac{d C{i}}{d t}=\frac{Q_{i}}{V_i}\left(C_{a r t}-\frac{C_{i}}{P_{i} V_{i}}\right)$$` ] `\(A_i\)` is amount of chemical, `\(Q_i\)` is blood flow, `\(C_{art}\)` incoming arterial blood concentration, `\(P_i\)` the tissue over blood partition coefficient, and `\(V_i\)` the volume of compartment `\(i\)`. --- background-image: url(https://i.ibb.co/bFtvTjp/IJN-86785-F02.png) background-size: 400px background-position: 95% 90% class: clear ![:scale 60%](https://www.dovepress.com/cr_data/article_fulltext/s86000/86785/img/IJN-86785-T01.png) --- background-image: url(https://i.ibb.co/5FFXtJS/Screenshot-from-2019-12-03-10-50-20.png) background-size: 350px background-position: 90% 80% # Different exposure routes .pull-left[ ## Inhalation `$$C_{\mathrm{art}}=\frac{Q_{\mathrm{pul}}\left(1-r_{\mathrm{ds}}\right) C_{\mathrm{inh}}+Q_{\mathrm{tot}} C_{\mathrm{ven}}}{Q_{\mathrm{pul}}\left(1-r_{\mathrm{ds}}\right) / P_{\mathrm{air}}+Q_{\mathrm{tot}}}$$` ## Ingestion `$$\frac{dA_{\mathrm{iv}}}{d t}=Q_{\mathrm{liv}}\left(C_{\mathrm{art}}-\frac{A_{\mathrm{liv}}}{P_{\mathrm{liv}} V_{\mathrm{liv}}}\right)-k_{\mathrm{met}} A_{\mathrm{liv}}+R_{\mathrm{ing}}$$` </br> </br> ] .footnote[ `\(A\)`: quantity; `\(Q\)`: flow rate; `\(r_{ds}\)`: deadspace ratio; `\(C\)`: concentration; `\(R_{ing}\)`: administration rate; `\(P\)` partition coefficient; `\(k\)` rate constant Bois F.Y., Brochot C. (2016) [Modeling Pharmacokinetics](https://link.springer.com/protocol/10.1007%2F978-1-4939-3609-0_3). In: Benfenati E. (eds) In Silico Methods for Predicting Drug Toxicity. Methods in Molecular Biology ] --- class:middle, center .font300[ # Computational toolkits ] --- # Computational toolkits ### Multiple software packages available to solve differential equations .font150[ - ASCL – “traditionally” used by many established PBPK modelers (but now discontinued!) - Berkeley Madonna – used in some PBPK modeling courses - MatLab – flexible interactive interface (more expensive, but more powerful) - GNU MCSim – specialized software for Bayesian uncertainty and population variability analyses ] ### All of them incorporate methods for “optimizing” the model fit by adjusting parameter values. --- # Computational toolkits .pull-left[ ## GNU MCSim **Simulation package, which allows you to:** - design and run simulation models (using algebraic or differential equations) - perform Monte Carlo stochastic simulations - do Bayesian inference through Markov Chain Monte Carlo simulations - has faster computing speed than other simulation software/packages (e.g., Asclx, Berkeley Madonna, RStan) ] .pull-left[ ## R **Programming language that allows you to:** - conduct statistical analysis (summarization, estimation) - visualize simulation results - use various packages to analyze results (e.g., CODA, BOA, rstan) - perform sensitivity analysis (e.g., sensitivity, pksensi) - access community support (e.g., Stack Overflow, R User groups) ] --- background-image: url(https://upload.wikimedia.org/wikipedia/commons/9/93/GPLv3_Logo.svg) background-size: 200px background-position: 50% 80% # Advantages of MCSim and R .center[.font125[*"Free and Open Source Software"* under GNU General Public License]] > - The freedom to run the program as you wish, for any purpose (freedom 0). > - The freedom to study how the program works, and change it so it does your computing as you wish (freedom 1). Access to the source code is a precondition for this. > - The freedom to redistribute copies so you can help others (freedom 2). > - The freedom to distribute copies of your modified versions to others (freedom 3). By doing this you can give the whole community a chance to benefit from your changes. Access to the source code is a precondition for this. --- background-image: url(http://lcolladotor.github.io/figs/2016-03-07-BiocParallel/parallel.gif) background-size: 750px background-position: 90% 40% # Advantages .font125[*"Parallel computing"*]  ### - Run multiple MCMC chains with multiple CPUs ### - High performance (cloud) computing .footnote[[*source*](http://lcolladotor.github.io/2016/03/07/BiocParallel/#)] --- # Advantages - Reproducible research .center[ ![:scale 84%](https://i.ibb.co/nBPdYgW/Screenshot-from-2019-12-03-17-24-16.png) ] .footnote[Reproducibility and Replicability in Science (2019) http://nap.edu/25303] --- background-image: url(https://aberdeenstudygroup.github.io/studyGroup/lessons/SG-T2-JointWorkshop/tidyverse.png) background-size: 500px background-position: 90% 90% # Conducting data analysis through R - Implement a wide variety of statistical and graphical techniques - Comprehensive research workflow and toolkits (e.g., RMarkdown) - Integration with low-level language (e.g., C, C++, Fortran) - Highly extensible through the use of user-submitted packages - Webapp development .font75[(e.g., http://webpopix.org/shiny/ShinyExamples.html)] .footnote[[Image source](https://aberdeenstudygroup.github.io/studyGroup/lessons/SG-T2-JointWorkshop/PopulationChangeSpeciesOccurrence/)] --- background-image: url(https://www.rstudio.com/wp-content/uploads/2018/10/RStudio-Logo-Flat.png) background-size: 300px background-position: 95% 95% # RStudio ### Free and open-source integrated development environment ### Powerful and user friendly programming interface ### Designed to make it easy to write scripts ### Easy to view and interact with the objects ### R project with version control (e.g., git) ### Support cloud computing https://rstudio.cloud/ ---
 ![](https://i.ibb.co/6vWf06v/Screenshot-from-2019-11-28-15-31-26.png) --- background-image: url(https://upload.wikimedia.org/wikipedia/commons/5/5a/Mcsimlogo.png) background-size: 100px background-position: 95% 90% # GNU MCSim .font75[ - The project started by Don Maszle and [Frederic Y. Bois](https://en.wikipedia.org/wiki/Fr%C3%A9d%C3%A9ric_Y._Bois) in UC Berkeley, 1991. It is written in standard C language as a model preprocessor. - First public release in 1993 (straight simulations with Monte Carlo modeling). > GNU MCSim is a general purpose modeling and simulation program which can performs "standard" or "Markov chain" Monte Carlo simulations. It allows you to specify a set of **linear or nonlinear algebraic equations** or **ordinary differential equations**. They are solved numerically using parameter values you choose or parameter values sampled from statistical distributions. Simulation outputs can be compared to experimental data for Bayesian parameter estimation (model calibration). ] .pull-left[ .font50[ - 6.1.0 (19 February 2019) - 6.0.1 (05 May 2018) - 6.0.0 (24 February 2018) - 5.6.6 (21 January 2017) - 5.6.5 (27 February 2016) - 5.6.4 (30 January 2016) - 5.6.3 (1 January 2016) - 5.6.2 (24 December 2015) - 5.6.1 (21 December 2015) - 5.6.0 (16 December 2015) - 5.5.0 (17 March 2013) - 5.4.0 (18 January 2011) - 5.3.1 (3 March 2009) - 5.3.0 (12 January 2009) - 5.2 beta (29 January 2008) - 5.1 beta (18 September 2006) - 5.0.0 (4 January 2005) - 4.2.0 (15 October 2001) - 4.1.0 (1 August 1997) - 4.0.0 (24 March 1997) https://www.gnu.org/software/mcsim/mcsim.html ] ] .pull-right[ .font140[Founder: *Frédéric Y. Bois*] Staff Toxicologist (Specialist), Reproductive and Cancer Hazard Assessment Section, CalEPA, Berkeley, USA, 1991-96 ] ??? This project mainly focus on using GNU MCSim This founder of this project is Dr. Frédéric Y. Bois. He had been worked in CalEPA as Staff Toxicologist for 5 years. --- # GNU MCSim Overview The *GNU MCSim* consists in two pieces, a **model generator** and a **simulation engine**:
 The model generator, **"mod"** - Created to facilitate structural model definition and maintenance, while keeping execution time short. You can code your model using a simplified syntax and use mod to translate it to `C` (`model.c`). The simulation engine, **"sim"** - A set of routines which are linked to your model during compilation to produce executable program (`mcsim.model`). After that, you can run simulations of your model under a variety of conditions, specify an associated statistical model, and perform simulations. --- # GNU MCSim Workflow .center[ ![:scale 90%](https://i.ibb.co/RNxBfN5/GNU-MCSIm-Workflow.png) ] --- # Types of Simulation **Simple simulation** - Straight simulations (set parameter values and initial conditions). **Used to:** *Model testing when building the model (e.g., mass balance)*
 **Monte Carlo simulations** - Perform repeated (stochastic) simulations across a randomly sampled region of the model parameter space. **Used to:** *Check possible simulation (under given parameter distributions) results before model calibration*
 **SetPoints simulation** - Solves the model for a series of specified parameter sets. You can create these parameter sets yourself or use the output of a previous Monte Carlo or MCMC simulation. **Used to:** *Posterior analysis, Local/global sensitivity analysis* --- background-image: url(https://i.ibb.co/Gx6xKrq/mcmc-diagram.png) background-size: 600px background-position: 50% 90% # Types of Simulation ### Markov-chain Monte Carlo (MCMC) simulation - Performs a series of simulations along a Markov chain in the model parameter space. - They can be used to obtain the Bayesian **posterior** distribution of the model parameters, given a statistical model, **prior** parameter distributions and data for which a **likelihood function** can be computed. - *GNU MCSim* can handle hierarchical statistical models as well. .footnote[ [Source](http://sbml.org/images/1/17/StatMeeting_F_Bois.pdf) ] --- background-image: url(https://i.ibb.co/0c8rQ4p/httk.png) background-size: 540px background-position: 50% 98% # MCSim-related R packages **httk: R Package for High-Throughput Toxicokinetics** .font75[ Robert G. Pearce, R. Woodrow Setzer, Cory L. Strope, Nisha S. Sipes, John F. Wambaugh ] > *MCSim* (Bois and Maszle 1997) was used for converting the model equations into C code, which is used with **deSolve** (Soetaert et al. 2016) in solving each system of equations. .right[ .font75[ *Journal of Statistical Software*; http://dx.doi.org/10.18637/jss.v079.i04 ] ] *GNU MCSim* model code  C code  **deSolve** package  Prediction --- # MCSim-related R packages **pksensi: R Package for Global Sensitivity Analysis in Pharmacokinetic Modeling** .font80[ Nan-Hung Hsieh, Brad Reisfeld, Weihsueh A. Chiu] > **pksensi** implements the global sensitivity analysis workflow to investigate the parameter uncertainty and sensitivity in pharmacokinetic (PK) models, especially the physiologically based pharmacokinetic (PBPK) model with multivariate outputs. .right[[![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version-last-release/pksensi)](https://cran.r-project.org/package=pksensi)] **Two types of model solver** `solve_fun()` *GNU MCSim* model code  C code  **deSolve** package  Prediction `solve_mcsim()` *GNU MCSim* model code  Prediction **Note:** `solve_mcsim()` is faster than `solve_fun()` --- background-image: url(http://devhumor.com/content/uploads/images/November2017/step-by-step-debugging.png) background-size: 450px background-position: 95% 90% # Disadvantages in MCSim and R ### Difficult learning curve (command line interface-based) ### Requires coding/programming skill ### Requires installation of extra program or package ### Requires **"debugging"** --- background-image: url(https://files.explosm.net/comics/comicsavegamenew.png) background-size: 400px background-position: 60% 90% # Git ### - Manage your code (models, inputs, R script) ### - Transfer your file (through GitHub or GitLab) ### - Collaboration work  .font60[.footnote[ https://xkcd.com/1597/ ]] --- background-image: url(https://upload.wikimedia.org/wikipedia/commons/5/58/Octocat_GitHub_Mascot.png) background-size: 200px background-position: 95% 90% # GitHub ![:scale 80%](https://www.linode.com/docs/development/version-control/how-to-install-git-and-clone-a-github-repository/git-github-workflow-1000w.png) --- class: hide-logo .center[![:scale 78%](https://i.ibb.co/LQ4Y6Bb/Screenshot-from-2019-11-28-15-00-44.png)] .footnote[https://github.com/USEPA] --- # High Performance Research Computing **The efficient way to conduct parallel computing** .center[![:scale 60%](https://i.ibb.co/c6ht46y/Screenshot-from-2019-11-28-15-10-21.png)] --- background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Tux.svg/150px-Tux.svg.png) background-size: 200px background-position: 90% 80% # Linux **The open source Unix-like operating systems for high performance research computing** ![:scale 55%](https://i.ibb.co/y592vn2/Screenshot-from-2019-11-28-15-17-34.png) --- # Summary - Basic pharmacokinetics - **A,D,M,E** each may affect internal dose, and differences between species or among individuals. - Role of pharmacokinetics in risk assessment - Exposure / concentration **prediction** - Pharmacokinetic modelling - Information from **physiology** and **chemistry** are common ways to characterize the concentration-time relationship. - Computational toolkits - The **open soure** computational tools (e.g., R & GNU MCSim) are powerful and can help us conduct the model simulation and data analysis --- class:middle, center .font300[ # Hands on Exercise ] --- # Hands on Exercise Task 1. **Exploratory analysis of PK data** (`code`: https://rpubs.com/Nanhung/SRP19_1) - Learn how to use R to conduct basic analysis for PK data Task 2. **PK model development** (`code`: https://rpubs.com/Nanhung/SRP19_2) - Learn how to use R and MCSim to build a model Task 3. **Parameter setting and model simulation** (`code` https://rpubs.com/Nanhung/SRP19_3) - Understand the parameter seting in PK model and conduct the simulation Task 4. **PBPK model development** (`code` https://rpubs.com/Nanhung/SRP19_4) - Instead of PK model, we need to know how to build a PBPK model Task 5. **Application of PBPK model** (`code` https://rpubs.com/Nanhung/SRP19_5) - Here, we have a well-built PBPK model and its parameters, let's apply the model in the exposure assessment --- # Hands on Exercise ## Task 1: **Exploratory analysis of PK data** - Now, we have a theophylline PK dataset. The purpose of this exercise is to develop the simple PK model and use it to describe the PK of theophylline. First, look into the theophylline dataset. The `Theoph` data frame has 132 rows and 5 columns of data from an experiment on the pharmacokinetics of theophylline. Then, find the Cmax and Tmax for each individual. ```r head(Theoph) ``` ``` ## Subject Wt Dose Time conc ## 1 1 79.6 4.02 0.00 0.74 ## 2 1 79.6 4.02 0.25 2.84 ## 3 1 79.6 4.02 0.57 6.57 ## 4 1 79.6 4.02 1.12 10.50 ## 5 1 79.6 4.02 2.02 9.66 ## 6 1 79.6 4.02 3.82 8.58 ``` - Plot the pharmacokinetic diagram for each individual. --- # Hands on Exercise ## Task 2: **PK model development** - Develop the non compartment model and compartment model in R and MCSim - Non compartment model `$$C(t) = \frac{F\cdot D \cdot ka}{V(k_a - k_e)}\cdot(\mathrm{e}^{-k_et}-\mathrm{e}^{-k_a{t}})$$` - Compartment model `$$\frac{dA_{gut}}{dt}=-k_aA_{gut}$$` `$$\frac{dA}{dt}=k_aA_{gut}-k_eA_e$$` `$$C=A/V$$` --- # Hands on Exercise ## Task 3: **Parameter setting and simulation** - Extract the chemical information from httk package ```r library(httk) parms <- httk::parameterize_1comp(chem.name = "theophylline") ``` - Use the parameters in the developed model and conduct the simulation - Compare the difference between data and the model simulation result (Cmax, Tmax) --- # Hands on Exercise ## Task 4: **PBPK model development** - Instead of simple PK model, in this exercise we want to apply the well developed PBPK model for 1,3 butadiene. - First, reproduce the simulation result from the published paper*. .footnote[ [*] Bois F.Y., Brochot C. (2016) [Modeling Pharmacokinetics](https://link.springer.com/protocol/10.1007%2F978-1-4939-3609-0_3). In: Benfenati E. (eds) In Silico Methods for Predicting Drug Toxicity. Methods in Molecular Biology, vol 1425. Humana Press, New York, NY ] --- # Inputs ```r C_inh <- approxfun(x = c(0, 120), y=c(10,0), method = "constant", f = 0, rule = 2) ``` ```r plot(C_inh(1:300), type="l", xlab = "Time (min)", ylab = "Butadiene inhaled concentration (ppm)") ``` ![](191209_srp1_files/figure-html/unnamed-chunk-7-1.svg) --- # Parameters and outputs ```r parameters <- c("BDM" = 73, # Body mass (kg) "Height" = 1.6, # Body height (m) "Age" = 40, # in years "Sex" = 1, # code 1 is male, 2 is female "Flow_pul" = 5, # Pulmonary ventilation rate (L/min) "Pct_Deadspace" = 0.7, # Fraction of pulmonary deadspace "Vent_Perf" = 1.14, # Ventilation over perfusion ratio "Pct_LBDM_wp" = 0.2, # wp tissue as fraction of lean mass "Pct_Flow_fat" = 0.1, # Fraction of cardiac output to fat "Pct_Flow_pp" = 0.35, # ~ to pp "PC_art" = 2, # Blood/air partition coefficient "PC_fat" = 22, # Fat/blood ~ "PC_wp" = 0.8, # wp/blood ~ "PC_pp" = 0.8, # pp/blood ~ "Kmetwp" = 0.25) # Rate constant for metabolism ``` ```r y <- c("Q_fat" = 0, # Quantity of butadiene in fat (mg) "Q_wp" = 0, # ~ in well-perfused (mg) "Q_pp" = 0, # ~ in poorly-perfused (mg) "Q_met" = 0) # ~ metabolized (mg) ``` --- # Model structure ```r # Define the model equations bd.model <- function(t, y, parameters) { with (as.list(y), { with (as.list(parameters), { # Define constants # Calculate flow and volumes # Calculate the tissue, blood, and air # Differentials for quantities # The function bd.model must return at least the derivatives list(c(dQ_fat, dQ_wp, dQ_pp, dQ_met), # derivatives c("C_ven" = C_ven, "C_art" = C_art)) # extra outputs }) # end with parameters }) # end with y } # end bd.model ``` --- ## Constants **Known constants** ```r # Known constants Height = 1.6 # use to calculate fraction of body fat Age = 40 # use to calculate fraction of body fat Sex = 1 # use to calculate fraction of body fat MW_bu = 54.0914 # butadiene molecular weight (in grams) ``` **Conversions from/to ppm** ```r ppm_per_mM = 24450 # ppm to mM under normal conditions ppm_per_mg_per_l = ppm_per_mM / MW_bu mg_per_l_per_ppm = 1 / ppm_per_mg_per_l ``` --- ## Flows and volumes **Air and blood flow** ```r # Calculate Flow_alv from total pulmonary flow Flow_alv = Flow_pul * (1 - Pct_Deadspace) # Calculate total blood flow from Flow_alv and the V/P ratio Flow_tot = Flow_alv / Vent_Perf # Calculate fraction of body fat Pct_BDM_fat = (1.2 * BDM / (Height * Height) - 10.8 *(2 - Sex) + 0.23 * Age - 5.4) * 0.01 # Calculate actual blood flows from total flow and percent flows Flow_fat = Pct_Flow_fat * Flow_tot Flow_pp = Pct_Flow_pp * Flow_tot Flow_wp = Flow_tot * (1 - Pct_Flow_pp - Pct_Flow_fat) ``` **Volumes** ```r # Actual volumes, 10% of body mass (bones…) get no butadiene Eff_V_fat = Pct_BDM_fat * BDM Eff_V_wp = Pct_LBDM_wp * BDM * (1 - Pct_BDM_fat) Eff_V_pp = 0.9 * BDM - Eff_V_fat - Eff_V_wp ``` --- ## Concentrations - tissues & blood ```r # Calculate the concentrations C_fat = Q_fat / Eff_V_fat C_wp = Q_wp / Eff_V_wp C_pp = Q_pp / Eff_V_pp # Venous blood concentrations at the organ exit Cout_fat = C_fat / PC_fat Cout_wp = C_wp / PC_wp Cout_pp = C_pp / PC_pp # Sum of Flow * Concentration for all compartments dQ_ven = Flow_fat * Cout_fat + Flow_wp * Cout_wp + Flow_pp * Cout_pp C_inh.current = C_inh(t) # to avoid calling C_inh() twice # Arterial blood concentration # Convert input given in ppm to mg/l to match other units C_art = (Flow_alv * C_inh.current * mg_per_l_per_ppm + dQ_ven) / (Flow_tot + Flow_alv / PC_art) # Venous blood concentration (mg/L) C_ven = dQ_ven / Flow_tot ``` --- ## Concentrations - air ```r # Alveolar air concentration (mg/L) C_alv = C_art / PC_art # Exhaled air concentration (ppm) if (C_alv <= 0) { C_exh = 10E-30 # avoid round off errors } else { C_exh = (1 - Pct_Deadspace) * C_alv * ppm_per_mg_per_l + Pct_Deadspace * C_inh.current } ``` --- ## Differentials for quantities ```r # Quantity metabolized in liver (included in well-perfused) dQmet_wp = Kmetwp * Q_wp # Differentials for quantities dQ_fat = Flow_fat * (C_art - Cout_fat) dQ_wp = Flow_wp * (C_art - Cout_wp) - dQmet_wp dQ_pp = Flow_pp * (C_art - Cout_pp) dQ_met = dQmet_wp ``` --- ## Outputs ```r # Define the computation output times t <- seq(from=0, to=1440, by=10) # Solve ODE library(deSolve) out <- ode(times=t, func=bd.model, y=y, parms=parameters) head(out) ``` ``` ## time Q_fat Q_wp Q_pp Q_met C_ven C_art ## [1,] 0 0.00000000 0.00000000 0.00000000 0.00000000 0.000000000 0.01606403 ## [2,] 10 0.02293618 0.03724892 0.07427798 0.06645654 0.003338318 0.01819035 ## [3,] 20 0.04722954 0.04026245 0.14189019 0.16431358 0.004379098 0.01885327 ## [4,] 30 0.07221315 0.04152080 0.20176415 0.26661643 0.005210310 0.01938270 ## [5,] 40 0.09777386 0.04256838 0.25471138 0.37175647 0.005941936 0.01984870 ## [6,] 50 0.12383371 0.04349410 0.30153555 0.47935418 0.006589697 0.02026129 ``` --- ```r plot(out) ``` ![](191209_srp1_files/figure-html/unnamed-chunk-12-1.svg) --- # Hands on Exercise ## Task 5: Apply the PBPK model - Based on the OSHA permissible exposure limit (PEL), the time-weighted average is 1 ppm. If a worker is under the exposure for a long time, what is the estimated blood concentration. .footnote[ https://www.cdc.gov/niosh/npg/npgd0067.html ]


--- layout: default ---
Please don't enter any personal information. All comments are public! You can edit or delete your comment within 15 minutes of submitting it.
Comments
Please don't enter any personal information. All comments are public! You can edit or delete your comment within 15 minutes of submitting it.


--- layout: default title: "Form Advance - TTWeb Admin Dashboard Template" parent: "forms" sub_parent: "forms" activePage: "form-advance" plugins: ["select2", "jquery_mask"] ---
ex. 99/99/9999
ex.<PHONE_NUMBER>
ex. 99-9999999
ex. 999-99-9999
ex. ~9.99 ~9.99 999
ex. 9999 9999 9999 9999


Djedkare Isesi (known in Greek as Tancheres) was a pharaoh, the eighth and penultimate ruler of the Fifth Dynasty of Egypt in the late 25th century to mid-24th century BC, during the Old Kingdom. Djedkare succeeded Menkauhor Kaiu and was in turn succeeded by Unas. His relatio...


Dashboard
You may create up to 5 checks
| Method | Protocol | URL | State | Details |
|---|---|---|---|---|
| You have no checks, please create one! |
{% renderTemplate("components/appHead.html", { head: {% JSON.stringify(head) %} }) %}
| Method | Protocol | URL | State | Details |
|---|---|---|---|---|
| You have no checks, please create one! |


{% extends 'base.html' %} {% import "bootstrap/wtf.html" as wtf %} {% block content %}
Submit your details here...


JUDSON Z THOMPSON
(****point donations are always appreciated)
About the Author
He lives vicariously through himself.
He once had an awkward moment, just to see how it feels.
Cuba imports cigars from him.
In museums, he is allowed to touch the art.
Interesting links:
SubReddits
Cringetopia
People of Walmart
International Affairs:
The War Zone - Logistics and development of military equipment
Cyber News
Random Table for assignment:
|
Intergalactic Conquest |
Death By Lightsaber |
| Storm Troopers |
✔ |
✔ |
| Darth Vader |
✔ |
✔ |
Created by the intergalatic evil empire
Located @: Lunar Moon Base


A digital agency specializing in UI/UX design and development of websites and mobile applications, animation, graphic design and branding.
We're a design agency specializing in mobile/web design and development, motion design, graphics and branding. Specializing in iOS and web development, mobile and web UI/UX, motion and graphic design, branding and content management.
We Create A Unique Web Design to Increase Your Page's Conversions.
The goals we set while designing for the web in order to achieve the best results are a unique design that is both flexible and substantial.


--- All About Kevin ---
Welcome to my about me page
Bio
I am 30 years old. I enjoy sitting by the fire and long walks on the beach.
Business
I am a creator at heart. I enjoy working with my hands and love the payoff when my initial vision is brought to life.
Goals
- Create amazing things
- Make a difference in the world
- Make people happy
- Have lotsa fun
Top 10 Favorite Cities (besides Puyallup, WA)
- Rome
- Monaco
- Paris
- Amsterdam
- London
- San Diego
- Treviso
- Dublin
- New York
- Nice


22 September 1998
Disease Outbreak Reported
WHO stresses importance of careful monitoring of Vibrio cholerae O139 strain
In 1992, the world was alarmed by a severe outbreak of cholera in the Bay of Bengal caused by a non-O1 strain of Vibrio cholerae, serogroup O139. The fast spread of this new strain to neighbouring countries and the notification of imported cases in developed countries, raised concern as to the possible occurrence of a new pandemic of cholera.
Vibrio cholerae O139 has been detected since then in 10 countries. This new strain continues to be confined to South-East Asia. In 1998, V. cholerae O139 has been isolated from 3 patients in Hong Kong Special Administrative Region of China and 3 in India.
Although no major outbreaks have been caused by V. cholerae O139 since 1994, the fear that this new strain could become a global threat is still present, particularly in Asia, where extremely heavy rainfalls and floods have contributed to an increase in cases and deaths due to cholera.
The WHO Global Cholera Task Force recommends that efforts to monitor the spread of V. cholerae O139 at a global level must be continued and/or strengthened.


---
layout: post
title: Free PDF storyboard template
date: '2017-12-13T06:33:05+01:00'
categories:
- Templates
picture_url: https://film-Storyboards.tumblr.com/post/168499873446/this-is-a-free-Storyboards-template-in-pdf-format
---
This is a free Storyboards template in PDF format on DIN A4 vertical (portrait) page, designed for print. This template has 5 frames per sheet each in 2:1 aspect ratio (Univisium). The layout is inspired by the beautiful Storyboards from Studio Ghibli.
The first column indicates cuts. Use it to number your shots—you can have several pictures for the same shot.
The second and main column stands for the pictures screen. It is where you draw or place your Storyboards frames.
Then there is a space for your script notes: action, dialogue, etc.
The last column, time, is for annotating the duration of your shots in seconds.
Print it out and start drawing on paper right away.
If you need an editable version of this template, you can find the Adobe InDesign version here: https://gum.co/Ghibli_En_idml_2x1.
If you are looking for the free 1.85 (Widescreen) version of this template, you can find it here: https://gum.co/ghibli-Storyboards-english


Your node must be HTTPS in order to connect to it via MyEtherWallet.com. You can [download the MyEtherWallet repo & run it locally](https://github.com/kvhnuke/etherwallet/releases/latest) to connect to your local node. Or, get free SSL certificate via [LetsEncrypt](https://letsencrypt.org/).
You may know this as your "Account #" or your "Public Key". It's what you send people so they can send you ETH. That icon is an easy way to recognize your address.
Your Address:
This Keystore / JSON file matches the format used by Mist & Geth so you can easily import it in the future. It is the recommended file to download and back up.
This is the unencrypted text version of your private key, meaning no password is necessary. If someone were to find your unencrypted private key, they could access your wallet without a password. For this reason, encrypted versions are typically recommended.
Private Key (unencrypted)
ProTip: If you cannot print this right now, click "Print" and save it as a PDF until you are able to get it printed. Remove it from your computer afterwards!
You arrived via a link that has the address, amount, gas or data fields filled in for you. You can change any information before sending. Unlock your wallet to get started.
Unlock your wallet to send ETH or Tokens directly from this page.
Warning! You are not connected to an ETH node.
Please use the node switcher in the top-right corner to switch to an ETH node. We do not support swapping ETC or Testnet ETH.
You cannot send with only your address. You must use one of the other options to unlock your wallet in order to send.
This page allows you to download different versions of private keys and re-print your paper wallet. You may want to do this in order to [import your account into Geth/Mist](http://ethereum.stackexchange.com/questions/465/how-to-import-a-plain-private-key-into-geth/). If you want to check your balance, we recommend using a blockchain explorer like etherscan.io.
You may know this as your "Account #" or your "Public Key". It's what you send people so they can send you ETH. That icon is an easy way to recognize your address.
Your Address:
This Keystore / JSON file matches the format used by Mist & Geth so you can easily import it in the future. It is the recommended file to download and back up.
This is the unencrypted text version of your private key, meaning no password is necessary. If someone were to find your unencrypted private key, they could access your wallet without a password. For this reason, encrypted versions are typically recommended.
Private Key (unencrypted)
ProTip: If you cannot print this right now, click "Print" and save it as a PDF until you are able to get it printed. Remove it from your computer afterwards!
**You need your Keystore File + password or Private Key** to access this wallet in the future. Please save & back it up externally! There is no way to recover a wallet if you do not save it. Read the [help page](https://wallet.akroma.io/#help) for instructions.
Akroma Web Wallet does not hold your keys for you. We cannot access accounts, recover keys, reset passwords, nor reverse transactions. Protect your keys & always check that you are on correct URL.
You are responsible for your security.
Disclaimer
Always backup your keys: Akroma Web Wallet is not a web application. You do not create an account or give us your funds to hold onto. No data leaves your computer / your browser. We make it easy for you to create, save, and access your information and interact with the blockchain.
We are not responsible for any loss: Akroma, Akroma Web Wallet, and the underlying libraries we use are under active development. There is always the possibility something unexpected happens that causes your funds to be lost. Please do not invest more than you are willing to lose, and please be careful.
Offical Text: The English version of our website is the official text.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.