Michael "Mike" L. Nguyen
Michael "Mike" L. Nguyen / February 19, 1987 - November 5, 2019
Private services will be held.
Cress Funeral Service
1310 Emerald Terrace
Sun Prairie, WI 53590
Michael "Mike" L. Nguyen / February 19, 1987 - November 5, 2019
Private services will be held.
Cress Funeral Service
1310 Emerald Terrace
Sun Prairie, WI 53590


My Team
Robert
Manager
ID:
111
Email:
<EMAIL_ADDRESS>Office number:
111
Pat
Engineer
ID:
222
Email:
<EMAIL_ADDRESS>GitHub:
pat
Jon
Intern
ID:
333
Email:
<EMAIL_ADDRESS>School:
University


The electron's spin gives rise to a magnetic moment \( \mathbf{\mu}_s=-\mu_B\mathbf{\hat{s}} \). Now the electron is moving in the electric field of the nucleus, so it experiences a magnetic field in its moving frame hich interacts with \( \mathbf{\mu}_s \). Also, since there is no external torque on the atom, a coupling between \( \mathbf{l} \) and \( \mathbf{s} \) must result in a constant total angular momentum \( \mathbf{j} \). The individual angular momenta \( \mathbf{l} \) and \( \mathbf{s} \) must be precessing around \( \mathbf{j} \) because the interaction \( -\mathbf{\mu}_s\cdot\mathbf{B} \) gives rise to a torque acting on each of them.
PRIORITY: Js throws a gazilion "Uncaught Errors" when you change \(s\) or \(l\), and stops when you stop the animation. Maybe it's because plotly can't catch up with the amount of animation updates...
Things to fix: mesh3d does not support legendgroups, so need to add a button that shows/hides all the cones.
Bug regarding the cone mesh. The cone 'face' isn't completely covered for some reason - maybe only have a circle instead?
For some reason the rotation speed for the vectors increases over time, and speeds up when you change the quantum numbers...
Need to add a featured view for two-electron systems - possibly also an option to view jj-coupling?
Need to add 3D annotations for the different vectors.
NOTE: Plotly scatter3d animations seem to reset the camera every frame, so you can only rotate the view when animation is stopped.


Number of teenagers reporting severe anxiety doubled over past seven years - survey
by Stephen McNeiceAround one in four young people in Ireland suffer from severe anxiety, according to a major survey on the state of youth mental health in Ireland.
More than 19,000 young people between 12 and 25 took part in the UCD and JIGSAW 'My World Survey 2' - the largest of its kind in Ireland.
It's a follow-up to the first My World Survey in 2012, and has found significant increases in the levels of anxiety and depression.
The new survey shows the number of teenagers (12-19 years) reporting severe anxiety rose from 11% to 22%, while it's up from 15% to 26% among young adults (18-25 years).
With regards depression, 15% of teenagers reported the problem as being severe or very severe, up from 7%, while the number of young adults experiencing depression is up 7% to 21%.
Dr Joseph Duffy, CEO of Jigsaw, said that while young people today are more aware of their mental health, social media is having a big impact:
He explained: "That really wasn't a significant feature back in 2011, 2012.
"For some young people, the longer they spend online might impact on their ability to actually form social networks, and they might be comparing themselves negatively in terms of body image or the extent of their friendship networks."
Dr Duffy added: "[The survey] tells us that an increasing number of young people are continuing to experience high levels of anxiety and depression.
"This not only poses a huge challenge for mental health services, but also to each one of us as adults.
"This study also shows that the presence of a consistently supportive and understanding adult in a young person's life is one of the most immediate and effective responses we can offer to a young person in distress".
The survey also highlights a drop in the number of teenagers reporting bullying, down six points to 39%, and in the numbers reporting to have ever drank alcohol, from 51% to 42%.


decsoltripiv
Given the nXn tridiagonal matrix T (T_{i,j}=0 for |i-j| > 1) attempts to obtain a lower bidiagonal matrix L (L_{i,j}=0 for i>j+1) and uniti upper band matrix (with at most two codiagonals) U (U_{i,i}=1, U_{i,j}=0 for i>j and j>i+2) such that LU=PT where P is a permutation matrix,
for details see book of Hang T. Lau, “A Java Numerical Library for Scientists and engineers|”, Chapman & Hall, 2004
Example: Can be run with F9 within the ScalaLab Editor
import java.text.DecimalFormat;
import numal.*;
public class Test_decsoltripiv extends Object {
public static void main(String args[]) {
int i;
double d[] = new double[31];
double sub[] = new double[31];
double supre[] = new double[31];
double b[] = new double[31];
double aux[] = new double[6];
for (i=1; i<=30; i++) {
sub[i]=i*2;
supre[i]=i;
d[i]=i+10;
b[i]=0.0;
}
b[1]=1.0; b[2]=12.0; b[3]=4.0;
aux[2]=1.0e-6;
Linear_algebra.decsoltripiv(sub,d,supre,30,aux,b);
b[2]--;
DecimalFormat fiveDigit = new DecimalFormat("0.00000E0");
System.out.println("AUX[3] and AUX[5]: " +
fiveDigit.format(aux[3]) + " " +
fiveDigit.format(aux[5]) +
"\nError in the solution: " +
fiveDigit.format(Math.sqrt(Basic.vecvec(1,30,0,b,b))));
}
}


Children protest severe pollution in India after school closures
Indian schoolchildren took part in protests on Sunday (November 17) against poor air quality, after schools closed to protect the health of students.
Schools in New Delhi will reopen on Monday (November 18) after a two-day shutdown caused by pollution levels, but air quality is likely to remain "very poor," a notch below the "severe" rating.
Toxic smog that surrounds the city has plunged air quality into the "severe" category several days this month, as data showed that a promise from Prime Minister Narendra Modi to eliminate burning of crop stubble in neighboring states has not worked.


rotten > Library > Conspiracy > Trilateral Commission
Trilateral Commission
- The three laterals are: Europe, US, Japan.
- Organized by David Rockefeller.
- Jimmy Carter among the founding members.
- In the 1980 U.S. Presidential election, three major candidates were Trilateral members: George HW Bush, Walter Mondale, John Anderson (independent.)
- Other members or former members: Alexander Haig, Zbigniew Brzezinski, Warren Christopher, Caspar Weinberger, Henry Kissinger, Robert McNamara, George Shultz, John D. Rockefeller IV, Tom Foley, W. Michael Blumenthal, Cyrus Vance, Elliot Richardson, Paul Volcker, Bill Clinton, Count Otto Lambsdorff.
- (members) Mayors: Tom Bradley, Andrew Young.
- (members) Journalists: Katharine Graham (Washington Post), David Gergen (U.S. News and World Report)
- Ronald Reagan disliked the Commission and what it stood for, but held a reception for it in 1984.
- Pat Robertson: The Commission springs "from the depth of something that is evil."
- John Connally: The Republican Party "will never nominate a man who belonged to the Trilateral Commission." Riiight.
- At any given time, has around 325 members, each serving a 3 year "term".
- Trilateral Commission official homepage
Timeline
| 1973 |
Trilateral Commission organized by David Rockefeller. |
| 11 Jun 1993 |
The Washington Times reports: "Presidential counsellor David Gergen resigned yesterday from the all-male Bohemian Club, three days after saying he would not run around naked at its annual Bohemian Grove encampment and insisting he would not quit. White House spokeswoman Dee Dee Myers announced the resignation along with Mr. Gergen's departure from 17 other interest groups, charities and public boards ranging from the Trilateral Commission, the Bilderberg Group and Council on Foreign Relations." |
Pornopolis |
Rotten |
Faces of Death |
Famous Nudes
|


Class
ScenarioStore
public final class ScenarioStore
The class for managing a set of scenarios identified by the arbitrary kind.
Initializers
init(kind:)
public init(kind: ScenarioKind)
Initialize a new store with given kind.
Parameters
| Name | Type | Description |
|---|---|---|
| kind | ScenarioKind |
A unique identifier of the secenarios managed by this instance. |


Renting
Reference
of Vehicle (
Car
):
01
Rentings
Rentings
Reference
Plate
Driving License
Rent-A-Car
begin
end
Payment Reference
Invoice Reference
Cancellation Reference
Price
XPTO
XPTO
XPTO
XPTO
XPTO
XPTO
XPTO
XPTO
XPTO
XPTO
Error
Cancel
Cancel Renting?
Checkout
Notification
Checking out?
Kilometers:


| Interface | Description |
|---|---|
| ConfirmStripeIntentParams | |
| StripeIntent |
An interface for methods available in
PaymentIntent |
| StripePaymentSource |
Represents an object that has an ID field that can be used to create payments with Stripe.
|
| Class | Description |
|---|---|
| AccountParams |
Represents a grouping of parameters needed to create a Token for a Connect account on the server.
|
| Address |
Model for an owner address
object in the Source api.
|
| Address.Builder | |
| BankAccount |
Model class representing a bank account that can be used to create a token
via the protocol outlined in
the Stripe
documentation.
|
| Card |
A model object representing a Card in the Android SDK.
|
| Card.Builder |
Builder class for a
Card model. |
| ConfirmPaymentIntentParams | |
| ConfirmSetupIntentParams | |
| Customer |
Model for a Stripe Customer object
|
| CustomerSource |
Model of the "data" object inside a
Customer "source" object. |
| PaymentIntent |
A PaymentIntent tracks the process of collecting a payment from your customer.
|
| PaymentMethod |
Model for a Payment Methods API
object.
|
| PaymentMethod.BillingDetails | |
| PaymentMethod.BillingDetails.Builder | |
| PaymentMethod.Builder | |
| PaymentMethod.Card | |
| PaymentMethod.Card.Builder | |
| PaymentMethod.Card.Checks | |
| PaymentMethod.Card.Checks.Builder | |
| PaymentMethod.Card.ThreeDSecureUsage | |
| PaymentMethod.Card.ThreeDSecureUsage.Builder | |
| PaymentMethod.CardPresent | |
| PaymentMethod.Ideal | |
| PaymentMethod.Ideal.Builder | |
| PaymentMethodCreateParams |
Model for PaymentMethod creation parameters.
|
| PaymentMethodCreateParams.Card | |
| PaymentMethodCreateParams.Card.Builder |
Used to create a
Card object with the user's card details. |
| PaymentMethodCreateParams.Ideal | |
| PaymentMethodCreateParams.Ideal.Builder | |
| SetupIntent |
A SetupIntent guides you through the process of setting up a customer's payment credentials for
future payments.
|
| ShippingInformation |
Model representing a shipping address object
|
| ShippingMethod |
Model representing a shipping method in the Android SDK.
|
| Source |
Model for a Sources API object.
|
| SourceCardData |
Model for data contained in the SourceTypeData of a Card Source.
|
| SourceCodeVerification |
Model for a
code verification object in the Sources API.
|
| SourceOwner |
Model for a owner object
in the Source api.
|
| SourceParams |
Represents a grouping of parameters needed to create a
Source object on the server. |
| SourceReceiver |
Model for a
receiver object
in the Sources API.
|
| SourceRedirect |
Model for a
redirect object in the source api.
|
| SourceSepaDebitData |
Model for the SourceTypeData contained in a SEPA Debit Source object.
|
| SourceSepaDebitData.Builder | |
| Stripe3ds2AuthResult | |
| Stripe3ds2AuthResult.Ares | |
| Stripe3ds2AuthResult.MessageExtension | |
| Stripe3ds2AuthResult.ThreeDS2Error | |
| Stripe3ds2Fingerprint | |
| Stripe3ds2Fingerprint.DirectoryServerEncryption | |
| Stripe3dsRedirect | |
| StripeIntent.RedirectData | |
| StripeIntent.SdkData | |
| StripeJsonUtils |
A set of JSON parsing utility functions.
|
| StripeModel |
Represents a JSON model used in the Stripe Api.
|
| StripeSourceTypeModel | |
| Token |
Tokenization is the process Stripe uses to collect sensitive card, bank account details, Stripe
account details or personally identifiable information (PII), directly from your customers in a
secure manner.
|
| Enum | Description |
|---|---|
| AccountParams.BusinessType | |
| PaymentMethod.Type | |
| Stripe3ds2Fingerprint.DirectoryServer | |
| StripeIntent.NextActionType | |
| StripeIntent.Status | |
| StripeIntent.Usage |
See
setup_intent.usage and
Reusing Cards.
|
| Annotation Type | Description |
|---|---|
| Address.RequiredBillingAddressFields | |
| BankAccount.BankAccountType | |
| Card.CardBrand | |
| Card.FundingType | |
| PaymentMethod.Card.Brand | |
| Source.SourceFlow | |
| Source.SourceStatus | |
| Source.SourceType | |
| Source.Usage | |
| SourceCardData.ThreeDSecureStatus | |
| Token.TokenType |


Plugin Information |
|---|
View IBM Security AppScan Source Scanner on the plugin site for more information. |
Project Description
This plugin is supported by Aspect Security.
The purpose of this plugin is to allow Jenkins to perform static code analysis (SCA/SAST) with IBM AppScan Source for Analysis with minimal configuration. AppScan Source for Analysis is a security tool provided by IBM that will scan application source code for vulnerabilities. Configuring AppScan Source to perform automated scanning with custom batch jobs or shell scripts can be a time-consuming and error-prone process. This Jenkins plugin greatly simplifies the process of automating AppScan Source by providing global settings and simple scan configuration within Jenkins.For more information on IBM AppScan Source, please visit the official IBM site http://www-03.ibm.com/software/products/en/appscan-source
Prerequisites
This plugin requires the following:
- A valid license for AppScan Source for Analysis and AppScan Source for Automation
Note: The automation license is required to unlock the command-line interface (cli) functionality - AppScan Source for Analysis must be installed on the same server as Jenkins
- The AppScan Source project or application files for the application(s) you are scanning (.PAF, .PPF, etc)
- Application source code and dependencies must already be referenced in the AppScan Source project or application files
Plugin Setup
Before using this plugin, a login token must be generated via the AppScanSrcCLI application. To generate a login token:
- Open a command prompt
- Navigate to the bin folder in your AppScan Source install folder
- Ex: cd c:\program files(x86)\IBM\AppScan Source\bin
- Execute the AppScan Source CLI login command
- AppScanSrcCli.exe login http://hostname:9443/ase username password -persist -acceptssl
- Be sure to replace hostname, username, and password with valid values for your installation
- This will create a file called ouncecli.token under c:\users{username}\.ounce\. Verify that this file exists and make note of the location
For additional reading on the login command, please see IBM's documentation: http://www-01.ibm.com/support/knowledgecenter/SSS9LM_9.0.3/com.ibm.rational.appscansrc.utilities.doc/topics/command_line_interface_commands_login.html
Plugin Configuration
- From the Jenkins homepage, click Manage Jenkins and then Configure System
- Scroll down the page and locate the section titled AppScan Source
- Click Add AppScan Source
- Fill out the AppScan Source form
\- AppScan Source Name: A name for this instance of AppScan Source. This is just to help manage environments that may have multiple installations
- AppScan Source Installation Directory: The path to the installation directory. Note: the default value is C:\Program Files (x86)\IBM\AppScanSource
- Scroll to the bottom and locate the section titled AppScan Source Configuration and fill out the form
\- AppScan Enterprise Hostname/Domain Name: The host name of your AppScan Enterprise server
- Login Token File Path: This is the path to the login token generated above. Default path is C:\Users{user}\.ounce\ouncecli.token
- Click Save
Using the plugin
- Create a new job or access an existing job
- Select "Configure"
- Select "Add build step" and select "Run AppScan Source"
- Complete the fields that appear:
- AppScan Source installation will show the name you provided for the installation on the global configuration screen. If you have not added an installation, please go the the Jenkins Configure System link under Manage Jenkins. If you only have one installation configured, the installation should be selected for you. If you plan to execute AppScan Source on multiple Jenkins nodes, you may need to configure multiple installation paths.
- Disable scan should be unchecked if you wish the scan to run
- Accept SSL Errors should be checked if you have not created a trusted certificate for your AppScan Source installation. In an Enterprise environment, this should not be checked, since you should be using a trusted certificate.
- Scan Workspace Directory is where scan artifacts, like WAFL and staging files will be placed. Scan results (.ozasmt file) will also be placed in this directory.
- Application file should point to a PAF or SLN file to scan.
- Click Save at the bottom
- Run the job.
Compatibility
This version of the plugin was tested with Jenkins 1.651.1 and IBM Security AppScan Source 9.0.3. Plugin should work with any version of AppScan Source 9.0.0 or newer.
Roadmap
Support automated publishing of scan results to AppScan Enterprise.
Execute application scans with IBM Security AppScan Source
For additional information about this plugin, please see the project's README on GitHub
Attachments:
JenkinsPluginAddSource.png (image/png)
JenkinsPluginAddSource2.png (image/png)
JenkinsPluginAddSourceDetails.png (image/png)
JenkinsSourceConfig.png (image/png)


Close
Well done!
You successfullyread this important.
Close
Heads up!
This alert needs your attention, but it's not super important.
Close
Warning!
Better check yourself, you're not looking too good.
Close
Oh snap!
Change a few things up and try submitting again.
Close
Well done!
You successfullyread this important.


Review In Progress
Welcome to I/O and this is our review on the iPhone X. This is a review in progress, so we will update this artcile as more things become apperent.
What do you think:
WANT IT!
Meh...
Don't like it
Whats happening today in the world of tech.
I'd love your feedback!
Swing by for a cup of , or leave us a note:


I’m a software engineer.
I am part of a security engineering team that develops an in-house tool for our company. I may not normally deal with.
Officially, my job is to provide comprehensive data analysis on live network traffic and sorting through tickets to help filter out threats from normal activity.
 Attacks designed to compromise or hurt your networks? I’m part of the team that helps prevent the bad guys from winning.
I’m a cybersecurity aficionado.
Do we want the background to be a slide show?


--- layout: page title: Language Identifiers redirect_from: "/display/docs/Language+Identifiers/" ---
The following table represents valid language Identifier and country Identifier pairs.
|
Locale |
Smartling Identifier |
|
{{SmartlingLocale.locale}} |
{{SmartlingLocale.locale_id}} |


| Hydrogeological Toolbox |
A set of functions used internally to compute the solutions and the logarithmic derivatives.
| ldiff | Approximate logarithmic derivative with centered differences |
| ldiffs | Approximate logarithmic derivative with Spline sampling |
| ldiffh | Approximate logarithmic derivative with Horne formula |
| stefhest | Stefhest inverse Laplace numerical transform |
| dehoog | de Hoog inverse Laplace numerical transform |
| lin_fit | Linear least squares |
| nli_fit | Non linear least squares |
| Hytool |
© 1998-2007 Philppe Renard and Co. Terms of Use Acknowledgments


|
Inventory Grid
an inventory grid similar to diablo
|
manager for the inventory board/grid More...
Public Member Functions | |
| virtual void | RemovePiece (InventoryPiece origin) |
| remove piece from board More... | |
| virtual InventoryPiece | RemovePiece (Vector2Int origin) |
| remove piece placed at coordinates More... | |
| virtual List< BoardSlot > | TryPlace (InventoryPiece piece, Vector2Int origin) |
| used for preview More... | |
| virtual List< BoardSlot > | TrySwapWithBoard (InventoryPiece currentOnBoard, InventoryPiece newpiece, Vector2Int origin) |
| check to see if we can swap piece, if so swap it returns count > 0 if successful, count == 0 if not successful More... | |
| virtual List< BoardSlot > | PlaceOnBoard (InventoryPiece piece, Vector2Int origin) |
| place on board at origin, returns board slots occupied if successful and list returns count 0 if not successful More... | |
| virtual void | CreateGrid () |
| create the grid, also calls the OnBoardSlotCreated More... | |
Public Attributes | |
| System.Action< InventoryPiece, List< BoardSlot > > | OnNewPiecePlaced |
| piece and slots occupied More... | |
| System.Action< InventoryPiece, InventoryPiece > | OnPieceSwapped |
| System.Action< InventoryPiece, List< BoardSlot > > | OnPieceRemoved |
| piece and slots removed More... | |
| System.Action< BoardSlot > | OnBoardSlotCreated |
| new slot created, sub for your own creation More... | |
Protected Member Functions | |
| InventoryPiece | RemovePiece (List< BoardSlot > removed) |
| helper to remove piece based on board slots More... | |
Protected Attributes | |
| Dictionary< GameObject, Vector2Int > | ui = new Dictionary<GameObject, Vector2Int>() |
| Dictionary< InventoryPiece, List< BoardSlot > > | SlotsOccupied = new Dictionary<InventoryPiece, List<BoardSlot>>() |
| List< BoardSlot > | Slots = new List<BoardSlot>() |
| BoardPreview | preview = new BoardPreview() |
| int | Rows = 6 |
| int | Columns = 9 |
Properties | |
| Dictionary< GameObject, Vector2Int > | IDS [get] |
| instance and slot id More... | |
| BoardPreview | Preview [get] |
| preview highlight, preview intance and preview status More... | |
manager for the inventory board/grid
|
virtual |
create the grid, also calls the OnBoardSlotCreated
| GridTransform | |
| CellPrefab | |
| PanelGrid |
|
virtual |
place on board at origin, returns board slots occupied if successful and list returns count 0 if not successful
| piece | |
| origin |
|
virtual |
remove piece from board
| origin |
|
protected |
helper to remove piece based on board slots
| removed |
|
virtual |
remove piece placed at coordinates
| origin |
|
virtual |
used for preview
| piece | |
| origin |
|
virtual |
check to see if we can swap piece, if so swap it returns count > 0 if successful, count == 0 if not successful
| currentOnBoard | |
| newpiece | |
| origin |
|
protected |
| System.Action<BoardSlot> GWLPXL.InventoryGrid.Board.OnBoardSlotCreated |
new slot created, sub for your own creation
| System.Action<InventoryPiece, List<BoardSlot> > GWLPXL.InventoryGrid.Board.OnNewPiecePlaced |
piece and slots occupied
| System.Action<InventoryPiece, List<BoardSlot> > GWLPXL.InventoryGrid.Board.OnPieceRemoved |
piece and slots removed
| System.Action<InventoryPiece, InventoryPiece> GWLPXL.InventoryGrid.Board.OnPieceSwapped |
|
protected |
|
protected |
|
protected |
|
protected |
|
get |
instance and slot id
|
get |
preview highlight, preview intance and preview status


exception class: {{transaction.reason}}
traceback:
public_key: {{transaction.public_key}}
signature: {{transaction.id}}
hash: {{transaction.hash}}
fee: {{transaction.fee}}
diffie-hellman public key: {{transaction.dh_public_key}}
relationship identifier: {{transaction.rid}}
relationship data:
public_key: {{transaction.public_key}}
signature: {{transaction.id}}
hash: {{transaction.hash}}
fee: {{transaction.fee}}
diffie-hellman public key: {{transaction.dh_public_key}}
relationship identifier: {{transaction.rid}}
relationship data:
version: {{block.version}}
target: {{block.target}}
nonce: {{block.nonce}}
merkleRoot: {{block.merkleRoot}}
index: {{block.index}}
special min: {{block.special_min}}
time: {{block.time}}
previous hash: {{block.prevHash}}
public_key: {{block.public_key}}
signature: {{block.id}}
hash: {{block.hash}}
public_key: {{transaction.public_key}}
signature: {{transaction.id}}
hash: {{transaction.hash}}
fee: {{transaction.fee}}
diffie-hellman public key: {{transaction.dh_public_key}}
relationship identifier: {{transaction.rid}}
relationship data:


System Architecture
Model:
Encapsulates application state; Responds to state query and state update; Notify views of changes.
View:
Renders the models; Requests updates from models; Allow controller to select view.
Controller:
Defines application behavior; Map user action to model updates; Selects view for response.
Features:
1. Navigation menu, Slider, Poster on home page
4. Bus trip scheduling
- List all bus trips
Bus trips
- Create a new bus trip
Create a new bus trip
- Delete a bus trip
- Update a bus trip information
- Filter bus trip fields to display only five fields
5. Route scheduling for a specific bus stop
6. Role management
- Create a new role
- Delete an existing role
- List users in a selected role
- Add a user to one role or multiple roles
- Remove a user from a role
Users in a role
7. User management
- Lock or unlock a user from using the system
- Reset a user's password
- Delete an existing user
- Create a new user in registration module


--- layout: page title: Feedback date: type: page published: false status: draft categories: [] tags: [] meta: _edit_last: '1' author: login: adminian email<EMAIL_ADDRESS>display_name: adminian first_name: '' last_name: '' ---
Want to give me feedback? Send me a tweet: @ianphilpot
Did Microsoft do something you don't like?


|
| def | x (self) |
| |
|
def | x (self, val) |
| |
| def | y (self) |
| |
|
def | y (self, val) |
| |
| def | __init__ (self, arg=None, x=None, y=None, **kwargs) |
| |
◆ __init__()
| def plotly.graph_objs.layout.grid.Domain.__init__ |
( |
|
self, |
|
|
|
arg = None , |
|
|
|
x = None , |
|
|
|
y = None , |
|
|
** |
kwargs |
|
) |
| |
Construct a new Domain object
Parameters
----------
arg
dict of properties compatible with this constructor or
an instance of plotly.graph_objs.layout.grid.Domain
x
Sets the horizontal domain of this grid subplot (in
plot fraction). The first and last cells end exactly at
the domain edges, with no grout around the edges.
y
Sets the vertical domain of this grid subplot (in plot
fraction). The first and last cells end exactly at the
domain edges, with no grout around the edges.
Returns
-------
Domain
◆ x()
| def plotly.graph_objs.layout.grid.Domain.x |
( |
|
self | ) |
|
Sets the horizontal domain of this grid subplot (in plot
fraction). The first and last cells end exactly at the domain
edges, with no grout around the edges.
The 'x' property is an info array that may be specified as:
* a list or tuple of 2 elements where:
(0) The 'x[0]' property is a number and may be specified as:
- An int or float in the interval [0, 1]
(1) The 'x[1]' property is a number and may be specified as:
- An int or float in the interval [0, 1]
Returns
-------
list
◆ y()
| def plotly.graph_objs.layout.grid.Domain.y |
( |
|
self | ) |
|
Sets the vertical domain of this grid subplot (in plot
fraction). The first and last cells end exactly at the domain
edges, with no grout around the edges.
The 'y' property is an info array that may be specified as:
* a list or tuple of 2 elements where:
(0) The 'y[0]' property is a number and may be specified as:
- An int or float in the interval [0, 1]
(1) The 'y[1]' property is a number and may be specified as:
- An int or float in the interval [0, 1]
Returns
-------
list
The documentation for this class was generated from the following file:
- C:/Users/Nathan/Documents/SP20/Software Engineering/plotly.py/packages/python/plotly/plotly/graph_objs/layout/grid/__init__.py


| Enum Constant and Description |
|---|
CURRENT
Accesses the current record.
|
FIRST
Finds the first record in the database.
|
LAST
Finds the last record in the database.
|
NEXT
Moves to the next record.
|
NEXT_DUP
Moves to the next record with the same key.
|
NEXT_NO_DUP
Moves to the next record with a different key.
|
PREV
Moves to the previous record.
|
PREV_DUP
Moves to the previous record with the same key.
|
PREV_NO_DUP
Moves to the previous record with a different key.
|
SEARCH
Searches using an exact match by key.
|
SEARCH_BOTH
Searches using an exact match by key and data (or pKey).
|
SEARCH_BOTH_GTE
Searches using an exact match by key and a GTE match by data (or pKey).
|
SEARCH_GTE
Searches using a GTE match by key.
|
| Modifier and Type | Method and Description |
|---|---|
static Get |
valueOf(java.lang.String name)
Returns the enum constant of this type with the specified name.
|
static Get[] |
values()
Returns an array containing the constants of this enum type, in
the order they are declared.
|
public static final Get SEARCH
Returns, or moves the cursor to, the record having a key exactly matching the given key parameter.
If the database has duplicate keys, the record with the matching key and lowest data value (or the lowest primary key, for secondary databases) is selected.
The operation does not succeed if no record matches.
public static final Get SEARCH_BOTH
Returns, or moves the cursor to, the record having a key exactly matching the given key parameter, and having a data value (or primary key) exactly matching the given data (or pKey) parameter. The data is matched for Database and Cursor operations, while the primary key is matched for SecondaryDatabase and SecondaryCursor operations.
If the database has duplicate keys, the search is performed by key
and data (or pKey) using the database Btree. If the database has does
not have duplicate keys, the search is performed by key alone using the
Btree, and then the data (or primary key) of the matching record is
simply compared to the data (pKey) parameter. In other words, using
this operation has no performance advantage over SEARCH
when
the database does not have duplicates.
The operation does not succeed (null is returned) if no record matches.
public static final Get SEARCH_GTE
Returns, or moves the cursor to, the record with a key that is greater than or equal to (GTE) the given key parameter.
If the database has duplicate keys, the record with the lowest data value (or the lowest primary key, for a secondary database) is selected among the duplicates with the matching key.
The operation does not succeed (null is returned) if no record matches.
public static final Get SEARCH_BOTH_GTE
Returns, or moves the cursor to, the record with a key exactly matching the given key parameter, and having a data value (or primary key) that is greater than or equal to (GTE) the given data (or pKey) parameter. The data is matched for Database and Cursor operations, while the primary key is matched for SecondaryDatabase and SecondaryCursor operations.
If the database does not have duplicate keys, the data (or pKey) is
matched exactly and this operation is equivalent to SEARCH_BOTH
.
The operation does not succeed (null is returned) if no record matches.
public static final Get CURRENT
Accesses the record at the current cursor position. If the cursor is
uninitialized (not positioned on a record), IllegalStateException
is thrown.
The operation does not succeed (null is returned) if the record at the current position has been deleted. This can occur in two cases: 1. If the record was deleted using this cursor and then accessed. 2. If the record was not locked by this cursor or transaction, and was deleted by another thread or transaction after this cursor was positioned on it.
public static final Get FIRST
Moves the cursor to the record in the database with the lowest valued key.
If the database has duplicate keys, the record with the lowest data value (or the lowest primary key, for a secondary database) is selected among the duplicates for the lowest key.
The operation does not succeed (null is returned) if the database is empty.
public static final Get LAST
Moves the cursor to the record in the database with the highest valued key.
If the database has duplicate keys, the record with the highest data value (or the highest primary key, for a secondary database) is selected among the duplicates for the highest key.
The operation does not succeed (null is returned) if the database is empty.
public static final Get NEXT
Moves the cursor to the record following the record at the current
cursor position. If the cursor is uninitialized (not positioned on a
record), moves to the first record and this operation is equivalent to
FIRST
.
If the database does not have duplicate keys, the following record is defined as the record with the next highest key. If the database does have duplicate keys, the following record is defined as the record with the same key and the next highest data value (or the next highest primary key, for a secondary database) among the duplicates for that key; or if there are no more records with the same key, the following record is the record with the next highest key and the lowest data value (or the lowest primary key, for a secondary database) among the duplicates for that key.
The operation does not succeed (null is returned) if the record at the cursor position is the last record in the database.
public static final Get NEXT_DUP
Moves the cursor to the record following the record at the current
cursor position and having the same key. If the cursor is uninitialized
(not positioned on a record), IllegalStateException
is
thrown.
If the database has duplicate keys, moves to the record with the same key and the next highest data value (or the next highest primary key, for a secondary database) among the duplicates for that key.
The operation does not succeed (null is returned) if there are no following records with the same key. This is always the case when database does not have duplicate keys.
public static final Get NEXT_NO_DUP
Moves the cursor to the record following the record at the current
cursor position and having the next highest key. If the cursor is
uninitialized (not positioned on a record), moves to the first record
and this operation is equivalent to FIRST
.
If the database has duplicate keys, moves to the record with the next
highest key and the lowest data value (or the lowest primary key, for a
secondary database) among the duplicates for that key; this effectively
skips over records having the same key and a higher data value (or a
higher primary key, for a secondary database). If the database does not
have duplicate keys, this operation is equivalent to NEXT
.
The operation does not succeed (null is returned) if there are no following records with a different key.
public static final Get PREV
Moves the cursor to the record preceding the record at the current
cursor position. If the cursor is uninitialized (not positioned on a
record), moves to the last record and this operation is equivalent to
LAST
.
If the database does not have duplicate keys, the preceding record is defined as the record with the next lowest key. If the database does have duplicate keys, the preceding record is defined as the record with the same key and the next lowest data value (or the next lowest primary key, for a secondary database) among the duplicates for that key; or if there are no preceding records with the same key, the preceding record is the record with the next lowest key and the highest data value (or the highest primary key, for a secondary database) among the duplicates for that key.
The operation does not succeed (null is returned) if the record at the cursor position is the first record in the database.
public static final Get PREV_DUP
Moves the cursor to the record preceding the record at the current
cursor position and having the same key. If the cursor is uninitialized
(not positioned on a record), IllegalStateException
is
thrown.
If the database has duplicate keys, moves to the record with the same key and the next lowest data value (or the next lowest primary key, for a secondary database) among the duplicates for that key.
The operation does not succeed (null is returned) if there are no preceding records with the same key. This is always the case when database does not have duplicate keys.
public static final Get PREV_NO_DUP
Moves the cursor to the record preceding the record at the current
cursor position and having the next lowest key. If the cursor is
uninitialized (not positioned on a record), moves to the last record
and this operation is equivalent to LAST
.
If the database has duplicate keys, moves to the record with the next
lowest key and the highest data value (or the highest primary key, for a
secondary database) among the duplicates for that key; this effectively
skips over records having the same key and a lower data value (or a
lower primary key, for a secondary database). If the database does not
have duplicate keys, this operation is equivalent to PREV
.
The operation does not succeed (null is returned) if there are no preceding records with a different key.
public static Get[] values()
for (Get c : Get.values()) System.out.println(c);
public static Get valueOf(java.lang.String name)
name
- the name of the enum constant to be returned.java.lang.IllegalArgumentException
- if this enum type has no constant with the specified namejava.lang.NullPointerException
- if the argument is nullCopyright (c) 2002, 2017 Oracle and/or its affiliates. All rights reserved.


The NgFor directive instantiates a template once per item from an iterable. The context for
each instantiated template inherits from the outer context with the given loop variable set
to the current item from the iterable.
Local Variables
NgFor provides several exported values that can be aliased to local variables:
index will be set to the current loop iteration for each template context.
last will be set to a boolean value indicating whether the item is the last one in the
iteration.
even will be set to a boolean value indicating whether this item has an even index.
odd will be set to a boolean value indicating whether this item has an odd index.
Change Propagation
When the contents of the iterator changes, NgFor makes the corresponding changes to the DOM:
When an item is added, a new instance of the template is added to the DOM.
When an item is removed, its template instance is removed from the DOM.
When items are reordered, their respective templates are reordered in the DOM.
Otherwise, the DOM element for that item will remain the same.
Angular uses object identity to track insertions and deletions within the iterator and reproduce
those changes in the DOM. This has important implications for animations and any stateful
controls
(such as <input> elements which accept user input) that are present. Inserted rows can be
animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state such
as user input.
It is possible for the identities of elements in the iterator to change while the data does not.
This can happen, for example, if the iterator produced from an RPC to the server, and that
RPC is re-run. Even if the data hasn't changed, the second response will produce objects with
different identities, and Angular will tear down the entire DOM and rebuild it (as if all old
elements were deleted and all new elements inserted). This is an expensive operation and should
be avoided if possible.
Syntax

...

...

The
NgFor
directive instantiates a template once per item from an iterable. The context for each instantiated template inherits from the outer context with the given loop variable set to the current item from the iterable.Local Variables
NgFor
provides several exported values that can be aliased to local variables:index
will be set to the current loop iteration for each template context.last
will be set to a boolean value indicating whether the item is the last one in the iteration.even
will be set to a boolean value indicating whether this item has an even index.odd
will be set to a boolean value indicating whether this item has an odd index.Change Propagation
When the contents of the iterator changes,
NgFor
makes the corresponding changes to the DOM:Angular uses object identity to track insertions and deletions within the iterator and reproduce those changes in the DOM. This has important implications for animations and any stateful controls (such as
<input>
elements which accept user input) that are present. Inserted rows can be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state such as user input.It is possible for the identities of elements in the iterator to change while the data does not. This can happen, for example, if the iterator produced from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the second response will produce objects with different identities, and Angular will tear down the entire DOM and rebuild it (as if all old elements were deleted and all new elements inserted). This is an expensive operation and should be avoided if possible.
Syntax

...

...

<template ngFor #item [ngForOf]="items" #i="index">
...
</template>
Example
See a live demo for a more detailed example.


>
This is part of the old website. New website begins at fontforge.github.io
Are you a web developer? Help us migrate this page on Github
FontForge is primarily an outline font editor, but it does have some facility for editing bitmap (and greymap, or anti-aliased) fonts. A useful term here is a "strike"; a strike is one particular size of a bitmap font. When FontForge displays a font, that font will contain at most one outline but potentially many bitmap (or greymap) strikes (for several different pixel sizes).
You might wonder if it is really necessary to provide bitmaps along with outlines given the high quality results of modern rasterizers, and for Latin (Greek, Cyrillic) fonts it may not be, but for CJK fonts at small pixel sizes a human eye can still make a better choice than even the best rasterizer. Back in the 1980s when Apple first adopted PostScript fonts they felt it was essential to have bitmaps to go with the outline -- so much so that it was not even possible to use a PostScript font without also providing at least one bitmap with it. Even today, when using a Type1 font on a mac there must be a bitmap font to point to it.
Of course Type1 fonts are a bit old-fashioned now, but the sfnt file format (the format used for both OpenType and TrueType fonts) supports embedded bitmap strikes along with the outline version of the font. These strikes will be used in preference to rasterizing the outline in any pixel sizes for which they are present.
If you have an sfnt with both an outline font and bitmap strikes you can open it directly with the File->Open command and FontForge will load all the bits and pieces.
You can also open a bitmap only font directly with the File->Open command, however if you have multiple strikes of the same underlying font in separate files, you will probably want to open only the first (or only the outline version) with Open, and use File->Import to merge the other strikes into one FontForge font.
Suppose you have Ambrosia.pfb
(an outline font),
Ambrosia-12.bdf
, and Ambrosia-24.bdf
(two bitmap
strikes, one 12 pixels high, one 24), and you want them all in one font.
First use File->Open to open Ambrosia.pfb,
then File->Import and select both of
the bitmap strikes (hold down the shift key).
On the other hand, if you have only two bitmaps:
Ambrosia-12.bdf
, and Ambrosia-24.bdf
, then use
File->Open to open either strike, and
use File->Import and import the other.
You may have noticed that Import has a checkbox labeled [] As
Background
. If you check this, then your bitmap font will not be loaded
as a font itself, but will be loaded into the background of the outline font
whence you can
Element->Autotrace
it to provide an outline font from a bitmap. Be warned: This produces fairly
bad results unless you have a large (100+ pixel) font to trace.
If you
want to add a bitmap strike with a given pixel size to a font then use
Element->Bitmap Strikes
Available
. Simply add the pixel size you are interested in to
the list at the bottom of the screen.
If you are more comfortable dealing in point sizes, be aware that those depend on screen resolution. This dialog shows you the conversion between point and pixel sizes for two standard resolutions. The resolutions differ depending on what windowing system you use.
You may add more than one pixel size, of course. You may also remove pixel sizes if you no longer want them.
Normally when you create a new strike it will be rasterized from the outline font -- if there is no outline font then FontForge will attempt to scale the biggest strike available to the new size (in most cases this will be fairly ugly, but it may be better than nothing.
There is also a checkbox [*] Create Rasterized Strikes (Not empty
ones)
at the bottom of the dialog. If you turn this off, then the
rasterization process described above will not happen, and any new strikes
will be created containing no glyphs (you can add glyphs later, of course).
In the old days of bdf and pcf fonts on X11 each font had a set of properties
attached to it. It is not clear to me whether these properties are still
useful as X11 moves to OpenType Bitmaps. They may be. At any rate FontForge
will store them both in BDF fonts and in OpenType Bitmap fonts. Each strike
may have its own set of properties. FontForge will generate them automatically
when you create a strike (and will retain them when it reads in a font that
has them). You may override the current values with the
Element-Bdf Info
dialog.
If you want to create a new font with no outlines, only bitmap strikes, you
would use File->New to create a new font,
and then Element->Bitmap Strikes
Available
to add some (empty) strikes to it. As soon as you add
a strike to a new font, the font will become a bitmap only font.
Apple has a bitmap only version of the sfnt file format, and X11 does too. Of course the two formats are slightly different. Windows has no support for a bitmap only sfnt format.
The View
menu of the Font
View (and the Metrics View) contains a list of all bitmap strikes in the
font. You may select which one will be displayed in the Font View. You may
also change the magnification at which a strike is displayed with
View->Bitmap Magnification... (it
can be hard to see the details of an 8 pixel font on a high resolution screen,
so you might want to display it at 3 times its actual size).
Many commands in the Font View will apply to all strikes (and the outline)
in the font. For instance
Edit->Copy
will copy the
outline glyph and all bitmap glyphs. Sometimes you only want to affect one
strike, if so then deselect
Edit->Copy From->All
Fonts
.
The Element->Build
commands will build accented bitmap glyphs just as it builds accented
outline glyphs.
If the Font View is displaying a bitmap strike and you double click on a character, then FontForge will bring up a bitmap editing window displaying that character in the current strike (rather than opening an outline editing window). If the character does not have a matching glyph in the current strike FontForge will create one by rasterizing the outline version of the font.
The bitmap editing window should be fairly self explanatory. The window is a simple bitmap editor. With the pencil tool, clicking on a pixel will make it change. The line tool will draw a straight line between the start and end points.
You can see the outline glyph in the background of the bitmap.
You can regenerate the bitmap (by rasterizing the outline) by pressing the
[Recalculate Bitmaps]
button.
Editing an anti-aliased greymap has the added complexity that you need to
select a color (actually a level of greyness) to be applied with the pencil.
There will be an additional palette with all possible greys for
this.
Sometimes you don't need a complete set of bitmap glyphs in a strike. Perhaps
the rasterizer does a good job for all glyphs except one. Then you can create
an empty strike (with
Element->Bitmap Strikes
Available
unchecking the [*] Create Rasterized Strikes
checkbox) and then select the one glyph you care about and say
Element->Regenerate Bitmap
Glyphs
.
Alternately you could create a fully rasterized strike and then select the
glyphs you don't need and say
Element->Remove Bitmap
Glyphs
.


I’m a PhD student in philosophy at St. John’s College, Cambridge. I study classification systems, measurement reactivity, and conceptual problems in psychiatry, psychology, and medicine. I have an MSci in Physics and Philosophy from King’s College London. My email address is hrs53 at cam.ac.uk.


Kitties Redo-Factory
Create your custom Kitty
Tabs
Cat Colors
Cat Shape & Anim
DNA:
Head and body
Mouth | Tail | Paws
Eyes
Ears
Pattern Mid Color
Pattern Sides Color
Eyes Shape
Patterns
Animation
Standard Cat
Random Cat
Finalize Cat
Enable Ethereum
metamask:
Get Accounts
account:
Create Cat
cat result:


TSqlMapXmlConfig class file.
Located in /Data/SqlMap/Configuration/TSqlMapXmlConfiguration.php (line 22)
| Class | Description |
|---|---|
| TSqlMapXmlConfiguration | TSqlMapXmlConfig class. |
| TSqlMapXmlMappingConfiguration | Loads the statements, result maps, parameters maps from xml configuration. |
Create an instance of an object give by the attribute named 'class' in the node and set the properties on the object given by attribute names and values.
Gets the filename relative to the basefile.
Get element node by ID value (try for attribute name ID as case insensitive).
Load document using simple xml.
For each attributes (excluding attribute named in $except) set the property of the $obj given by the name of the attribute with the value of the attribute.
Documentation generated on Sun, 11 Jan 2009 20:23:56 -0500 by phpDocumentor 1.3.0RC4


List
type
class
A linked-list of elements. The list is composed of two-elements arrays that are chained together. It's optimized so that adding or removing an element doesn't imply to copy the whole array content everytime.
Constructor
new
()
Creates a new empty list.
Instance Variables
length
(default,null) :
Int
The number of elements in this list.
Instance Methods
add
( item : List.T ) :
Void
Add an element at the end of the list.
clear
( ) :
Void
Makes the list empty.
filter
( f : List.T ->
Bool
) :
List
<List.T>
Returns a list filtered with
f
. The returned list will contain all elements
x
for which
f(x) = true
.
first
( ) : Null<List.T>
Returns the first element of the list, or null if the list is empty.
isEmpty
( ) :
Bool
Tells if a list is empty.
iterator
( ) : Iterator<List.T>
Returns an iterator on the elements of the list.
join
( sep :
String
) :
String
Join the element of the list by using the separator
sep
.
last
( ) : Null<List.T>
Returns the last element of the list, or null if the list is empty.
map
<X>( f : List.T -> map.X ) :
List
<map.X>
Returns a new list where all elements have been converted by the function
f
.
pop
( ) : Null<List.T>
Removes the first element of the list and returns it or simply returns null if the list is empty.
push
( item : List.T ) :
Void
Push an element at the beginning of the list.
remove
( v : List.T ) :
Bool
Remove the first element that is
== v
from the list. Returns
true
if an element was removed,
false
otherwise.
toString
( ) :
String
Returns a displayable representation of the String.


TermsAndConditions
Contents |
Terms of Use for code.kx.com
GENERAL TERMS
Code.kx.com (“the Site”) is made available by Kx Systems, Inc. (“Kx”) and contains software, documentation, information and other materials ("the Content") provided by Kx and third party contributors (“Contributors”) solely for use by authorized and registered users of the Site.
ACCESS AND USE OF THE SITE AND ITS CONTENT IS SUBJECT TO THE FOLLOWING TERMS OF USE. ALL USERS OF THE SITE, BY REGISTERING, ACCESSING, BROWSING OR USING THE SITE, AGREE TO BE BOUND BY THESE TERMS OF USE.
Kx may, at any time, in its sole discretion and without notice, remove or modify any Content on this site, including Content provided by Contributors. Kx may also, at any time and without notice, terminate any user’s access to the Site or the ability of any Contributor to add Content to the Site.
This Site contains proprietary notices and copyright information, the terms of which must be observed and followed. The Content on this Site may contain technical inaccuracies or typographical errors and may be changed or updated without notice.
Kx and Contributors to the Site assume no responsibility regarding the accuracy of the Content, and use of the Content is at the user’s own risk. Kx provides no assurances that any reported problems with any Content will be resolved. Except as otherwise expressly stated below or in connection with specific Content, neither Kx or Contributors grant any licenses to any copyrights, patents or any other intellectual property rights to the Content. Kx and the Contributors do not want to receive confidential information from you through this Site. Any information or material sent to Kx or Contributors will be considered NOT to be confidential.
Users of the Site are prohibited from posting or transmitting to or from this Site any unlawful, threatening, libelous, defamatory, obscene, scandalous, inflammatory, pornographic, or profane material, or any other material that could give rise to any civil or criminal liability under the law.
Kx makes no representations whatsoever about any other Web site that you may access through this Site. When you access another, please understand that it is independent from Kx, and that the Kx has no control over the content on such Web site. In addition, a link to a non-Kx Web site does not mean that Kx endorses or accepts any responsibility for the content or the use of such Web site. It is up to you to take precautions to ensure that whatever you select for your use is free of such items as viruses, worms, Trojan horses and other items of a destructive nature.

 KX AND THE CONTRIBUTORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY AND NONINFRINGEMENT OF THE CONTENT.
Kx and the Contributors reserve the right to seek all remedies available at law and in equity for violations of these Terms of Use, including but not limited to the right to block access from a particular Internet address to this Site.
LICENSE GRANT
Except for the “Kdb+ for Mortals,” “Q for Mortals” and "Q for Mortals 2" tutorials and any Content which is locked from copying or downloading, Kx and the Contributors hereby grant to the users of the Site a worldwide, unrestricted, royalty free, non-exclusive license to use, make, reproduce, prepare derivative works of, publicly display, publicly perform, transmit, sell, distribute, sublicense or otherwise transfer the Content and derivative works thereof, and authorize third parties to do any, some or all of the foregoing including, but not limited to, sublicensing others to do any some or all of the foregoing indefinitely. The licensed Content, as described and limited above, includes all Content provided by Contributors, and any ideas, concepts, know-how and techniques contained in the licensed Content.
Notwithstanding the previous paragraph, users are prohibited from using, or authorizing any other person to use, the Content to develop any code, program, application, derivative work or any other printed or electronic matter that has functionality similar to Kx’s Kdb+ software.
Users agree that although Kx and Contributors grant the licenses set forth above, neither Kx nor the Contributors offer any assurance that the Content does not infringe the patent or other intellectual property rights of any other person or entity. Kx and the Contributors disclaim any liability to Users for claims brought against them by any other person or entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted above, each User assumes sole responsibility to secure any intellectual property rights needed to lawfully use the Content. For example, if a third party patent license is required to allow a User to distribute Content, it is User’s responsibility to obtain that license from the appropriate third party before distributing the Content. Contributors hereby represent and warrant that, to the best of their knowledge, they have sufficient rights in the Content they contribute to grant the foregoing rights and licenses. Notwithstanding the foregoing, all logos and trademarks contained on this Site are and remain the property of their respective owners. No licenses or other rights in or to such logos and trademarks are granted to users.
These Terms of Use are governed by the laws of the State of California and the intellectual property laws of the United States of America without giving effect to any principles of conflicts of laws. No legal action under these Terms of Use may be brought more than one year after the cause of action arose. The exclusive jurisdiction for any claim or action arising out of or relating to these Terms of Use or any use of this Site shall be filed only in the state or federal courts located in the County of Santa Clara, State of California. Claimants agree and submit to the exercise of personal jurisdiction of such courts for the purpose of litigating any claim or action.
PROCEDURE FOR SUBMITTING NOTICE OF COPYRIGHT INFRINGEMENT
Kx respects the intellectual property rights of others and ask our Contributors and Users to do the same. If you believe that copyrighted work of yours has been copied and is accessible on or through this Site in a way that constitutes copyright infringement, please notify Kx and provide it with the following information:
- 1. Your name, address, telephone number and email address.
- 2. A description of the specific location on this Site where the material that you claim is infringing is located.
- 3. A description of the copyrighted work that you claim has been infringed.
- 4. Identification of the location where the original or an authorized copy of the copyrighted work exists, for example the name of the publication in which it has been published or the URL of the Web site where it is posted.
- 5. A statement by you that you have a good faith belief that the disputed use is not authorized by the copyright owner, its agent or the law.
- 6. A statement by you, made under penalty of perjury, that the above information is accurate and that you are the copyright owner or are authorized to act on the copyright owner's behalf.
- 7. Your electronic or physical signature, as the owner of the copyright or as the person authorized to act on behalf of the owner of the copyright interest.
Claims of copyright infringement should be submitted to Kx Systems, Inc., Attention General Counsel, 555 Bryant Street #375, Palo Alto, CA 94301. You may also call<PHONE_NUMBER>.
Kx Systems, Inc. Version: October 18, 2011


In this notebook, the effect of aggregation in isobaric labeling proteomics data will be explored. The aggregation method will be summing of reporter ion peak heights (intensity values). Data characteristics of peptide-spectrum-matches (PSMs), which have no aggregation, will be compared to peptides (limited aggregation) and to proteins (more aggregation).
This is a complex mouse brain mixture, digested, split into 6 aliquots, labeled with 6 TMT reagents, and mixed in a series of dilutions. The relative volume amounts were in these proportions: 25 : 20 : 15 : 10 : 5 : 2.5. The biological sample was from the Gail Mandel lab at OHSU.
The data were generated on a Thermo Fusion using the SPS MS3 method (McAlister 2014). The peptide identifications and reporter ion intensities were generated using an in-house pipeline with Comet (Eng 2013) as the search engine. The PAW pipeline (Wilmarth 2009) does a direct processing of the RAW files to extract MS2 scans for Comet and the reporter ions from the corresponding MS3 scans (Chambers 2012). Comet results are filtered using a target/decoy strategy with accurate mass conditional score histograms. Basic parsimony logic is used to generate protein and peptide reports.
An additional protein grouping algorithm is also employed to group protein families having large fractions of identical common peptides. The final list of proteins is used as the context for shared and unique peptide determinations. Only unique peptides in that context are used in the TMT quantification. All unique PSM reporter ions are summed into protein intensity totals for each channel. We will compare some properties of the reporter ions at the PSM level, the peptide level (combined copies and charge states), and the protein level. This analysis is similar to what was shown in Figure 3 of Wenger et al., 2011.
Chambers, M.C., Maclean, B., Burke, R., Amodei, D., Ruderman, D.L., Neumann, S., Gatto, L., Fischer, B., Pratt, B., Egertson, J. and Hoff, K., 2012. A cross-platform toolkit for mass spectrometry and proteomics. Nature biotechnology, 30(10), p.918. link
Eng, J.K., Jahan, T.A. and Hoopmann, M.R., 2013. Comet: an open‐source MS/MS sequence database search tool. Proteomics, 13(1), pp.22-24. link
McAlister, G.C., Nusinow, D.P., Jedrychowski, M.P., Wühr, M., Huttlin, E.L., Erickson, B.K., Rad, R., Haas, W. and Gygi, S.P., 2014. MultiNotch MS3 enables accurate, sensitive, and multiplexed detection of differential expression across cancer cell line proteomes. Analytical chemistry, 86(14), pp.7150-7158. link
Wenger, C.D., Phanstiel, D.H., Lee, M.V., Bailey, D.J. and Coon, J.J., 2011. COMPASS: A suite of pre‐and post‐search proteomics software tools for OMSSA. Proteomics, 11(6), pp.1064-1074. link
Wilmarth, P.A., Riviere, M.A. and David, L.L., 2009. Techniques for accurate protein identification in shotgun proteomic studies of human, mouse, bovine, and chicken lenses. Journal of ocular biology, diseases, and informatics, 2(4), pp.223-234. link
# load the R libraries
library(tidyverse)
library(stringr)
library(edgeR) # used in Parts 2 and 3
The PSM data comes from the reporter ion table for each MS3 scan extracted directly from the converted RAW file. This is unfiltered data. This is not a list of PSMs associated with the identified peptides and proteins.
The peptide and protein CSV files are extracted from the normal PAW report files for proteins and peptides. For this analysis, we do not need to know the identities of any of the proteins or peptides. Only the columns of the reporter ion intensities (for all 10 reporter ion channels) were extracted for the CSV files.
This was a 6-plex labeling kit so there were only 6 of the 10 (or 11) channels that actually have labeled peptides. We will drop the unused 4 channels after reading the CSV files and set some more descriptive column names based on the dilution factors.
# Set up to select the proper columns and label them
keep <- c(1, 2, 5, 6, 9, 10)
labels = c("a_25", "b_20", "c_15", "d_10", "e_5", "f_2.5")
# read in the PSM dataset, keep the 6 columns, and set labels
psm_start <- read_csv("psm_tmt.csv")
psm_start <- psm_start[keep]
colnames(psm_start) <- labels
# PAW Grouped peptides
peptide_start <- read_csv("grouped_peptide_summary_TMT_8.csv")
peptide_start <- peptide_start[keep]
colnames(peptide_start) <- labels
# PAW grouped proteins
protein_start <- read_csv("grouped_protein_summary_TMT_8.csv")
protein_start <- protein_start[keep]
colnames(protein_start) <- labels
We will do some heavy-handed data filtering for this analysis. We will remove any rows in the data frames that have any zero values. We will be doing log transformations of intensities for some plots so we have to do something with zero values, or we will get mathematical errors. The choices are to drop rows with zeros or to do some sort of zero replacement. We will pick the easier (but more heavy-handed) option.
This is not quite true as the PAW pipeline normally does a zero replacement when only a few channels out of the set are zeros. The smallest non-zero peak height intensities are about 330 from this first-generation Fusion instrument in the SPS MS3 mode. A value of 50 was used as the replacement for zeros only for proteins.
Depending on the type of data being imported, "missing" data may be denoted by an actual zero or a blank. The zeros get converted to 0.0; the blanks become NA (not available) or NAN (not a number). To drop rows with NA values, we would need a slightly different logical test. The topic of what to do with missing data in TMT experiments is not trivial and also depends on data aggregation. You can read more here.
See how many rows we have in the data frames before and after the filtering steps:
# filter out rows with any missing data points and see how many rows remain
psms <- psm_start[apply(psm_start, 1, function(x) all(x > 0)), ]
print("PSMs (before and after filtering zeros):")
format(c(nrow(psm_start), nrow(psms)), digits = 0, big.mark = ',')
peptides <- peptide_start[apply(peptide_start, 1, function(x) all(x > 0)), ]
print("Peptides (before and after filtering zeros):")
format(c(nrow(peptide_start), nrow(peptides)), digits = 0, big.mark = ',')
proteins <- protein_start[apply(protein_start, 1, function(x) all(x > 0)), ]
print("Proteins (before and after filtering zeros):")
format(c(nrow(protein_start), nrow(proteins)), digits = 0, big.mark = ',')
We can also look at the 6 column sums to see that we actually have a proper dilution series.
When we have repeated code patterns (we are doing the same thing to PSMs, peptides, and proteins), it might be worth the time to create a function that we can call multiple times. This can increase potential for code reuse and reduce the chance to make typing and/or logic errors. It is easier to debug/modify one function rather than multiple blocks of similar code. These print statements are in the 6 versus half a dozen category (it is a toss-up). If you are doing a lot of cutting and pasting in a notebook, it might be time to write a function.
# check column sums for PSMs, peptides, and proteins
print("PSMs column sums:")
format(round(colSums(psms), digits = 0), big.mark = ",")
print("Peptide column sums:")
format(round(colSums(peptides), digits = 0), big.mark = ",")
print("Protein column sums:")
format(round(colSums(proteins), digits = 0), big.mark = ",")
Let's look at the distributions for the PSM-level data first. The x-axis is the log, base 2, of the intensities. Each dilution series is a separate, color-coded plot. Density distributions are kernel density estimates, which is a smoothed intensity histogram. ggplot needs tidy data in long format to make histograms or density plots, so we need to use the "gather" function.
show_densities <- function(df, xmin, xmax, title) {
# makes density distributions of the log2 intensities
# df - data frame with TMT intensities
# xmin, xmax - x axis limits
# title- plot title
# get data in long form
df_long <- gather(log2(df), key = "dilution", value = "intensity")
# make the density plots colored by dilution
ggplot(df_long, aes(x = intensity, fill = dilution)) +
geom_density(alpha = 0.2) +
ggtitle(title) +
xlim(xmin, xmax)
}
# compare PSM intensity (peak heights) distributions
show_densities(psms, 5, 25, "PSM data")
There is a low intensity drop out or "notch" at a log2 intensity of 11. It is more pronounced for the 5 and 2.5 dilution series where the reporter ion intensities are smaller.
This "notch" has been reported previously:
Hughes, C.S., Zhu, C., Spicer, V., Krokhin, O.V. and Morin, G.B., 2017. Evaluating the Characteristics of Reporter Ion Signal Acquired in the Orbitrap Analyzer for Isobaric Mass Tag Proteome Quantification Experiments. Journal of proteome research, 16(5), pp.1831-1838.
# compare peptide intensity (peak heights) distributions
show_densities(peptides, 5, 25, "Peptide data")
# compare protein intensity (peak heights) distributions
show_densities(proteins, 0, 30, "Protein data")
We required at least two peptides per protein, so most protein intensities are aggregated from several PSMs. This seems to average out the notch (the small bumps still at 11-ish) and the distributions look much better. The low peak in the proteins at log2 intensity of 5.6 is from the zero-replacement value of 50. We can see that the need for replacing missing data depends strongly on the amount of digest in the channel and is only occurring in the 2.5 and 5 dilution channels.
We will use the average of the 6 intensities as the x-axis and plot each dilution series (the different reporter ion channels) against that average vector. We will use different colors for each dilution series channel and overlay 6 scatter plots in one figure. We will show the scatter plots with linear axis scales, so we can better see the behavior of the underlying data. We will add a straight trend line for each series.
# helper function for scatter plots
show_scatter <- function(df, title) {
# makes linear scale scatter plots (all series against reference)
# df - tidy data frame with intensities and average reference vector
# title - plot title
# add the reference column (average) and put into long form for ggplot
df$ref <- rowMeans(df)
gg_df <- gather(df, key = dilution, value = intensity, a_25:f_2.5)
# make the full range scatter plot
full <- ggplot(data = gg_df, aes(x = ref, y = intensity)) +
geom_point(aes(color = dilution, shape = dilution), alpha = 0.5) +
geom_smooth(aes(color = dilution), method = "lm") +
ggtitle(title)
# expanded scale
expanded <- ggplot(data = gg_df, aes(x = ref, y = intensity)) +
geom_point(aes(color = dilution, shape = dilution), alpha = 0.5) +
geom_smooth(aes(color = dilution), method = "lm") +
coord_cartesian(xlim = c(0, 500000), ylim = c(0, 500000)) +
ggtitle(str_c(title, " (expanded scale)"))
print(full)
print(expanded)
}
We have not done any filtering for the PSMs other than removing zeros. They are the raw peak heights. There will be duplicates of the same peptides. There will also be signals from contaminants and decoys.
# scater plots for PSMs
show_scatter(psms, "raw PSMs")
The different dilution series are separating by intensities. The separation is better for more intense PSMs and the scatter in the data increases as the intensities gets smaller towards the origin. Overall, the data has a lot of variability.
These have been filtered a bit more than the PSMs were. The peptides are aggregated from just the 1% FDR PSMs. Matches to contaminants and decoy have been removed. We have done parsimonious protein inference and an additional protein grouping step. Shared and unique peptide status were determined from the final list of reported proteins. Any shared peptides have been excluded (this was done in Excel before exporting the CSV file). These are only the peptides associated with the confidently identified and quantifiable proteins.
# scater plots for peptides
show_scatter(peptides, "Peptides")
Peptides look a lot better than raw PSMs. That may not be a completely fair conclusion, however. We might want to do more work and select just the PSMs associated with these peptides to see whether it was the filtering of the peptides or the aggregation of PSMs up to peptides that is making the peptide data look better than the PSM data.
From the numbers at the top of the notebook, there are 60K PSMs that reduce to 20K peptides. We have about a 3-fold reduction in number of data points. This is an intermediate degree of data aggregation.
Like the peptides, any contaminants and decoy proteins have been excluded. The protein totals only include unique peptides. Zero values were replaced by a value of 50. The PAW pipeline has a few places where replacement of zero intensities could happen. I have finally come to the conclusion that the best place to do that (if at all) is at the final protein intensity level. There is quite a lot (8-fold) of aggregation when going from peptides (20K) to proteins (2.7K).
# scater plots for proteins
show_scatter(proteins, "Proteins")
The aggregation of PSMs and peptides to total protein intensities has a pretty dramatic improvement on the consistency of the data (how close the proteins are to the trend lines) over the full dynamic range. We might expect some increased scatter at low protein intensities as the number of data values being combined into the protein totals goes down. We will do some calculations to see how much tighter the data become as a function of aggregations level below after we take a little detour into TMM normalization (part of the edgeR R package).
We will also make data frames for MA style plots. Those plots have transformed axes (log2 ratios on y-axis, and log10 average intensity on x-axis). We will do the average intensity in log10 scale (that is easier to mentally "unlog" to get back to intensities). We will do the ratios (M-values) in log2 scale since that is more commonly used for fold changes.
MA plots are fold change on the y-axis (typically log2 of expression ratios) and a log10 average intensity on the x-axis. We have the average intensity as the reference column. The log10 of that will be our x-axis values. The ratio of each dilution series to the reference will be the y-axis (as log2 of the ratio). Each dilution series should be a horizontal line located at the expected ratio. The dilution series will stack vertically with the more concentrated series (25) on top.
# MA style plot for PSMs
show_MA_plot <- function(df, title) {
# transforms the data and makes MA plots (all versus reference)
# df - data frame with intensities and reference vector
# title - plot title
# take ratios relative to reference then log transform
df$ref <- rowMeans(df)
log_df <- log2(df[1:6] / df$ref) # these are log 2
log_df$ref <- log10(df$ref) # this stays in log 10
# we need data in tidy long form
gg_log_df <- gather(log_df, key = dilution, value = log_ratios, a_25:f_2.5)
# compute the expected horizontal lines
ratios <- log2(colMeans(df)[1:6] / colMeans(df)[7])
# make the plot
ggplot(data = gg_log_df, aes(x = ref, y = log_ratios)) +
geom_point(aes(color = dilution, shape = dilution), alpha = 0.3) +
geom_hline(yintercept = ratios) +
xlab("log ref intensity") +
ggtitle(title)
}
# make some MA plots for PSMs
show_MA_plot(psms, "PSMs (MA plot)")
The "notch" was not apparent in the scatter plots. We see it here as a top-left to bottom-center swath of missing points. The natural scale of TMT data is the intensity values. Both axes in MA plots are transformations of the native data. The y-axis in MA plots is typically auto-scaled to the range of fold-changes. Data sets with large fold changes look similar to data sets with small fold changes. The scatter plots are more true to the data, and differences in the data characteristics tend to produce scatter plots that look different.
# make some MA plots for peptides
show_MA_plot(peptides, "Peptides (MA plot)")
# make some MA plots for proteins
show_MA_plot(proteins, "Proteins (MA plot)")
Peptides look better behaved than PSMs, but we still have a lot of overlap between data from the different dilution series. Granted, the differences between many of the dilution values are rather small. The protein data is much reduced in scatter about the expected ratio solid black lines and the different dilution series are pretty well resolved from each other. The lower left diagonal line of data points in the proteins plot comes from the zero replacement values that are mostly associated lower intensities and with the 2.5 and 5 series. Note that the fold changes between the upper series (25, 20, and 15) are all small.
The log scales and vertical separation by relative expression level let us see what is going on at lower abundances more clearly than the fan-like scatter plots. Weak reporter ion signals have more asymmetry in their scatter about the horizontal lines (biased towards points below the expected horizontal lines). We see this mostly for the 5 and 2.5 series data. Less diluted samples (25, 20) also have increasing variance at low intensities, but do not seem to have as much asymmetry in the scatter.
There are two factors that are important in measurements: accuracy and reproducibility. Accuracy for this data is not that interesting. The measured dilution factors and the known dilution factors are in good agreement (see next cell). The trend lines in the scatter plots and the black, horizontal lines in the MA plots show that the data separate in intensity by the expected dilutions. There is quite a lot of published evidence that the SPS MS3 method improves the dynamic range and accuracy of isobaric labeling. As might be expected, there is a clear trend that lower intensity data has more uncertainty than higher intensity data.
# how close were the measured dilution factors?
tot_int <- sum(colSums(proteins))
unit <- tot_int / sum(c(25, 20, 15, 10, 5, 2.5))
round(colSums(proteins) / unit, 2)
Reproducibility means that if we measured the same thing multiple times we would get a set of values that are close to each other. We have 6 measurements of the same sample here, but the same amount of the sample was not measured each time. However, we know the dilution factors so we can basically undo the dilutions with some data normalizations. Then we can get 6 repeated measures and check the data reproducibility. A common metric for reproducibility is the coefficient of variation (CV), so we can compute the CV for each data frame row (either individual PSMs, peptides, or proteins) after normalizing the data to remove the dilution factors. Since we will have thousands of CV values, we will look at the distributions of the CV values. We have seen that aggregation seems to reduce data dispersion (scatter). We can compute median CV values and interquartile ranges for PSMs, peptides, and proteins.
We have many options for normalizing the data. We can use the known dilution factors to "undo" the pipetting differences. We could also measure the grand intensity totals for each channel and use single, global scaling factors to match the totals. The Bioconductor package edge seems to work well for statistical testing in TMT experiments and it incorporates a nice trimmed mean of M-values normalization algorithm developed for these types of omic datasets.
Robinson, M.D. and Oshlack, A., 2010. A scaling normalization method for differential expression analysis of RNA-seq data. Genome biology, 11(3), p.R25.
While normalization in edgeR involves a single function call, understanding exactly what is done to the data is surprisingly hard. edgeR does not create tables normalized data and then do the statistics on the normalized data. The modeling in edgeR uses the normalization factors as terms in the statistical model, so they kind of stay hidden.
One confusing thing about normalization in edgeR is that there are really two sequential normalization steps rather than just one. After loading data into a DGEList object in edgeR, you can examine the object. This is a "list" object in R, a heterogeneous data container. The table of data values (counts for RNA-Seq or intensities for TMT) is a data frame ("counts" slot) in the list. Another data frame is the "sample" information. This has sample names, group memberships (e.g. control or treatment), library sizes, and (potentially) TMM normalization factors. If you are not familiar with edgeR, the User's Guide is well written. It does assume some familiarity with R and with statistical modeling - some additional readings may be needed.
# loading the edgeR library was done at the top of the notebook
# load data into DGEList objects (counts are intensities, group are sample labels)
# the original data frames have added columns so we need just the first 6 cols
# PSMs first
y_psms <- DGEList(counts = psms[1:6], group = factor(labels))
y_psms$samples
# peptides next
y_peptides <- DGEList(counts = peptides[1:6], group = factor(labels))
y_peptides$samples
# finally, proteins
y_proteins <- DGEList(counts = proteins[1:6], group = factor(labels))
y_proteins$samples
The norm.factors column is 1.0 in all cases. Does this mean that there will be will not be any data normalization? No, data is adjusted by library size in edgeR. What does that mean? It means that each column is going to be divided by the library size (the column sum) so that the scaled intensites will sum up to 1.0 for each sample. This puts all of the data on the same relative scale, but fractional numbers are not very easy to understand. edgeR has a "cpm" function that puts the data on a counts-per-million scale so that the numbers are easier to interpret.
For fun, let's do some manipulations of the protein data (in the cell above). We will verify that the column sums are the library size numbers.
# these are the original column sums (they should match the library sizes)
round(colSums(proteins[1:6]), 0)
The column sums and library factors are the same. If we divide by the column sums (the library factors), then each channel will sum up to 1.0.
# dividing by library sizes makes each sample sum to 1.0
scaled_proteins <- sweep(proteins[1:6], 2, y_proteins$samples$lib.size, FUN = "/")
round(head(scaled_proteins), 8)
colSums(scaled_proteins)
Let's make them sum up to 1 million, i.e. let's make a cpm scale.
# make our own cpm scale
cpm_proteins <- scaled_proteins * 1000000
round(head(cpm_proteins), 0)
colSums(cpm_proteins)
The numbers on a cpm scale are easier to compare to each other than as fractional numbers. Compare the above to the cpm function in edgeR:
# use the cpm function in edgeR
round(head(cpm(y_proteins)), 0)
colSums(cpm(y_proteins))
Even though the "norm.factors" are 1.0, edgeR is still going to do the library size scaling even if the calcNormFactors function is not called. The calcNormFactors runs the TMM normalization on top of the library size scaling. I suspect that the TMM algorithm works better on "partially" normalized data.
TMM stands for the trimmed mean of M-values. The trimming in TMM is sort of a two-dimensional trimming. Some of the highest abundance and some of the lowest abundance values are removed. We are looking for large fold-changes (in both directions) so TMM assumes that the large and small M-values (the log ratios) should also be trimmed. That kind of leaves all of the stuff in the "middle", which is assumed to be at the same expression levels between samples. TMM computes global scaling factors (single factors) that makes the middle stuff as similar as possible.
The TMM algorithm is very sensible when study designs match its assumptions. Most experiments I read about and have analyzed tend to be compatible with TMM assumptions. There are always exceptions, and it is really important to understand the conceptual "bigger picture" of any normalization algorithm. Only appropriate normalization methods that apply to a given experimental design should ever be used. This is NOT a try all and pick the best one exercise!
We can run the trimmed mean of M-values algorithm and look at the "normalization" factors. Then we can re-run the "cpm" function after the TMM step and see if the result is the same as above.
# compute TMM factors - they get added to $samples
y_proteins_tmm <- calcNormFactors(y_proteins)
# round(y_proteins_tmm$samples$norm.factors, 6)
y_proteins_tmm$samples
# see what column sums we get after a cpm function call now that there are TMM factors
round(colSums(cpm(y_proteins_tmm)), 0)
round(mean(colSums(cpm(y_proteins_tmm))))
The libraries are very different in size (due to the sample dilutions), yet the "norm.factors" are all close to 1.0. This is because the TMM factors are in addition to the library size scaling. The way the "norm.factors" work is to adjust the effective library sizes. If the "lib.size" values are multiplied by the "norm.factors", then the column divided by the effective library size, you get the TMM normalized result.
If we call the "cpm" function after we have done the TMM normalization, we no longer get one million for each column total. Some column totals are a bit more and some are a bit less than 1 million. The average grand total is still basically 1 million (within rounding errors), so the up and down corrections are pretty balanced.
We can compute the normalization factors by hand (below) and make our own cpm data frame. We should get the same column totals as above.
# adjust the library sizes by the TMM factors to get the real library size factors
real_factors <- y_proteins_tmm$samples$lib.size * y_proteins_tmm$samples$norm.factors
# apply the factors to get the TMM normalized data table (fractional scale)
proteins_tmm_norm <- sweep(proteins[1:6], 2, real_factors, FUN = "/")
# put TMM normalized data on a one million scale
by_hand_cpm <- proteins_tmm_norm * 1000000
round(head(by_hand_cpm), 0)
round(colSums(by_hand_cpm), 0)
round(mean(colSums(by_hand_cpm)))
We see that edgeR always does a library size normalization step. The optional trimmed mean of M values normalization is in addition to the library size normalization, and the TMM factors are library size adjustment factors. The TMM factors scale the library sizes, which are in the denominators, so you have to divide, not multiple, by the TMM factors.
What was the point to Section 2? We saw that the library size corrections in edgeR basically "undo" the dilutions. We can do even a little bit more tweaking to get the six channels as similar as possible by adding TMM normalizations. edgeR has a cpm function that returns a data frame with the data points normalized and with data values that are on a nice scale.
If we take the data that was loaded into edgeR above, we can normalize the channels, and make cpm data frames. That will put all 6 channels on a similar scale, and then we can compute the coefficients of variance (CVs). We will print out the distribution summaries and compare boxplots.
# make multi-dimensional scaling plots to see if series are similar
plotMDS(calcNormFactors(y_psms), main = "PSMs")
plotMDS(calcNormFactors(y_peptides), main = "Peptides")
plotMDS(calcNormFactors(y_proteins), main = "Proteins")
The 5 and 2.5 dilutions are a little too weak in intensities to be as similar to the other dilutions as we might like. If we drop those two dilutions, we still have 4 for the CV calculation. We can define a function to do the edgeR steps (TMM normalization and cpm conversion) and then compute the CV distribution.
# define a function for normalizing data and computing CVs
get_cv <- function(DGE) {
# normalizes edgeR data, makes cpm scale, computes CV distribution
# DGE - edgeR DGEList object
# returns a CV distribution vector
# get a cmp scale table of normalized data
CPM <- as.data.frame(cpm(calcNormFactors(DGE)))
# compute CVs for first 4 channels (drop the 5 and 2.5 dilutions)
cv <- 100 * apply(CPM[1:4], 1, sd) / rowMeans(CPM[1:4])
}
# compute the CVs and look at the distribution summary numbers
psm_cvs <- get_cv(y_psms)
peptide_cvs <- get_cv(y_peptides)
protein_cvs <- get_cv(y_proteins)
print("PSM CVs:")
summary(psm_cvs)
print("Peptide CVs:")
summary(get_cv(y_peptides))
print("Protein CVs:")
summary(get_cv(y_proteins))
There are some differences between the median and mean CVs (above) because the distributions are not symmetric. They tail on the larger CV side.
BP <- function(cv, ymax, title) {
# returns a labeled boxplot
# cv - vector of CV values
# ymax - upper limit for plot
# title - main plot title
# make the box plot and label the median
bp <- boxplot(cv, ylim = c(0, ymax), notch = TRUE, main = title)
label <- text(x = 0.65, y = boxplot.stats(cv)$stats[3],
labels = round(boxplot.stats(cv)$stats[3], 1))
list(bp, label)
}
# compare some box plots of the CV distributions
par(mfrow = c(1, 3))
plot.label <- BP(get_cv(y_psms), 100, "PSMs")
plot.label <- BP(get_cv(y_peptides), 100, "Peptides")
plot.label <- BP(get_cv(y_proteins), 100, "Proteins")
par(mfrow = c(1, 1))
Protein intensities have smaller variances (tighter scatter plots and smaller median CVs) and increased dynamic range compared to PSM or peptide level measures. There is also a dramatic reduction in the number of data points. There are 22-fold fewer proteins than PSMs and almost 8-fold fewer proteins than peptides. Summing filtered PSM reporter ions into protein totals is an effective and simple way to aggregate TMT data.
The differences in the dilutions provided a nice context to see what typical data normalizations in edgeR do to data. While we diluted the same sample on purpose, it was still the same sample. Many normalization methods can correct for differences in sample loading, which is one extreme way to think about the dilutions.
We were able to use "normalization" to make the samples similar so that we could compute quantities like CV values. Data sets with large numbers of technical replicates are hard to find. That is why we spent some effort to get a little more mileage out of this data.
R and notebooks (or R Markdown in RSudio are powerful frameworks for being able to manipulate and visualize data. We discovered that the FT instruments from Thermo can have some data idiosyncrasies like the "notch". We would never have seen that if we had not taken the time to look.
# log the R session (we should always end notebooks with this)
sessionInfo()


Scanning for a particular LE advertisement containing a matching manufacturer data section and above a certain RSSI threshold. This scenario requires Scenario 2 or 4 to run on another Windows platform in close proximity of this one. Press Run button to begin scanning. Received advertisements are shown below.