Electrofishing App Changelog
NOTE: This is a legacy document. Newer releases can be found in
GitHub Releases
2.0.0 May 2, 2022
- Switch to Firebase hosting and new domains.
- Point to GIS services on the WRI machines.
-
Begin incremental removal of Dojo and adoption of React (#232).
- Make header more responsive in smaller layouts
- Upgrade most development tooling to more current packages.
- Remove new station gp service and hit feature service directly instead.
-
Return actual error message from server on failed submissions (#240).
- Restrict free type text boxes to the number of characters of the corresponding database field.
1.9.5 Apr 30, 2020
- Fix bug causing bulk uploads with decimal numeric values to fail.
1.9.4 Apr 23, 2020
- Fix bug related to multiple reports being submitted simultaneously.
1.9.1 Oct 28, 2019
-
Remove permanent id field from station popup (#56).
1.9.0 Sep 26, 2019
-
Link streams & lakes with stations (#195).
-
-
Move streams/lakes to SDE database and associated create relationship classes with the Stations feature
class.
- Add stream/lakes selection to new station dialog and make it required.
-
Fix bug causing multiple equipment items to have duplicate guids (#197).
-
Add "Water Id" to station marker popup (#56).
1.8.2 Aug 1, 2019
-
Tweaks for deployment on DWR server (#196).
1.8.1 June 26, 2018
- Confirm that bulk data upload works with a "COUNT" field and updated test data accordingly.
- Better error messages in some areas.
-
Removed the skipping of the "COUNT" field in the Catch tab when tabbing with the keyboard (#170).
-
Remove the minus button for pass and transect grid tabs (#171).
-
Better scrolling to make the successful submit message visible and added a "Done" button (#172).
1.8.0 June 14, 2018
- Fix bugs related to persistent caching of inprogress data.
-
Moved "Anode Shape" into the anode grid (#141).
-
Fixed bug preventing some fields in the Location tab from being cleared on a successful report submission or the
cancel button being pressed (#167).
1.7.1 June 12, 2018
-
Fix bug preventing reports from being submitted (#164).
-
Fix bug causing incorrect fields to be shown in the Equipment tab (#142).
-
Pre-populate field values when adding new equipments (#66).
1.7.0 June 7, 2018
-
Add a confirmation alert when deleting a pass or transect (#154).
-
Fix a bug preventing the submission of reports (#155).
- Better clean up of "More Info" dialog data when a fish is deleted.
-
Prevent new rows from being added to the Anode grid by tabbing (#140).
-
Add validation between the wetted width and starting bank values (#146).
-
Moved required splats (*) to headers for Station and Stream Reach (#118).
-
Add new "Count" column to catch grid preventing the need for entering duplicate rows (#49).
- Fix a bug causing up and down arrows to skip rows in grids.
- Fix a bug causing the right arrow to skip the Species column in the catch grid.
-
Switch "Measurement" column in the more info diet tab grid from text to numeric input (min: 0, no max) (#156).
1.6.0 May 25, 2018
- Better clean up on report cancel
- Upgrade the esri-leaflet and leaflet libraries to their latest versions.
- Update Transmitter Freq field to be type=number
- Fix a bug related to adding notes to fish.
-
Eliminate duplicate requests to the server for domain lists (#96).
- Add a minus button to allow users to remove catch passes and transects.
-
Add a better error message when bad stream data causes the location verification to fail (#123).
-
Add decimals to Bankfull Width and Wetted Width fields (#151).
-
Remove "(kHz)" from Transmitter Freq. field (#150).
-
Add units and increase upper limit to 3000 for Turbidity Field (#149).
- Remove Vegetation Density Field (#148).
-
Increase max value for Cathode Length field from 121 to 305 (#145).
-
Remove upper limit for Backwater Area field (#143).
-
Add additional required fields to Location tab (#118).
1.5.0 May 17, 2018
-
Swapped over/understory pick lists (#122).
-
Add Megahertz field to Tags tab in Fish dialog (#72).
-
Overwrite all codes with descriptions for domains (#97).
- Add Transect Grid to Habitat Tab (#54).
- Refactor Anode-related Fields (#62).
-
Added support for bulk data upload for catch data only via CSV (#82).
-
Fix bug causing "NaN" to show up as a value for empty numeric grid cells (#119).
-
Fixed bug causing a never-ending loop when selecting "[other]" within a grid drop down (#75).
1.4.1 April 5, 2018
-
Move 'Survey Purpose' to Location tab (#110).
-
Increase number of matches shown on map search (#117).
-
Rename a selection choice in a domain list (#120).
-
Allow for one decimal point in 'pH' field (#114).
-
Increase upper threshold of values in the '# Netters' field (#112).
1.4.0 March 22, 2018
-
Add units of measurement and new fields to Habitat tab (#60).
-
Add Additional Fields to Equipment Tab (#43).
-
Allow submissions with no fish entered (#79).
-
Go to Location tab after successful report submission (#81).
-
Add additional fields to Location Tab (#45).
-
Add "Hard Body Part Collection" to Fish Dialog (#44).
- Diet Tab unit tweaks (#52).
- Switch Over/Under-story Domains (#78).
- Additional Tag Types (#73).
-
Add asterisks (*) to all fields required for submission (#58).
- Add "Survey Purpose" to Method Tab (#59).
-
Remove "No Weight" and "Too Small" buttons (#46).
-
Remove Voltage from required fields list (#80).
-
Change coordinate box layout orientation to horizontal (#57).
-
Focus the last row in the grid after the "Delete" button is pressed (#51).
-
Delete button should not remove the last row (#50).
- Radio Button Group Contrast (#68).
-
Increase the weight of %3Chr%3E tags (#64).
-
Increase number of matches shown on stream map search (#55).
1.3.0 Nov 14, 2016
-
Rework batch workflow so that you enter rows first (including optional lengths) then batch weight (#7).
-
Fixed but causing the batch drop down to be visible after switching to a new tab (#20).
-
Added a summary of the count of fish per pass by species that is displayed before the report is submitted to the
server (#10).
-
Hide the success message after submitting a report after 5 seconds (#24).
1.2.0 Nov 7, 2016
-
Fixed a bug preventing the more info dialog from opening after submitting a report (#14).
- Upgraded Leaflet (mapping library) to v1.
- Added DWR streams & lakes layers (#11).
-
Implemented local caching of all in progress and submitted report data (#29).
- Upgraded change log format (#19).
-
Fixed bug causing the stream search box to overlap all other components (#28).
-
Clear anode shape when selecting raft equipment type (#23).
-
Better styling of the verify location button and related error message (#27).
-
Made the additional notes text area larger (#27).
-
Split habitat page into columns to better use screen real estate (#27).
-
Remember species and length type on new row added (#25).
-
Better error messages when verifying locations (#22).
1.1.0 Sept 20, 2016
- Upgraded all 3rd party libraries to their latest versions.
- Added grunt tasks.
- Converted to Web Mercator base maps.
-
Database schema tweaks to cathode length, voltage and thymus category (#3).
- Refactor/redesign the method tab (#2).
-
Fixed bug that allowed invalid numeric inputs to be submitted to the database (#17).
-
Added "Mouse wheel zooming" setting to settings dialog (#5).
-
Made the new station dialog map larger and synchronized its extent with that of the main maps (#9).
-
Added a subtle visual cue (bold) to rows that have additional data attached to them via the diet, tag, health
and notes dialog (#12).
1.0.0 January 3, 2014
- Fixed layout bug with grid scrolling. Closes #28662.
- Fixed bug that prevented the more info dialog from showing in certain situations. Closes #28676.
- Batch function now calculates '0' for rows if no weight was entered. Closes #28666.
-
Dropdowns have [other] option now that allows the user to create new options. We still need to decide what
happens on the back end with this. Ref #22892.
- Added basic test that verifies that data was stored in the database correctly. Closes #28508.
0.13.0 December 19, 2013
- Fixed bug related to adding new passes. Ref #28578.
- Added "Notes" tab and associated text area in the more info dialog. Ref #27683.
-
Expanded batch functionality to allow batching with no weights. Also reworked workflow to prevent the user from
having to manually add blank rows before running a batch. Ref #27685.
-
Created separate buttons for the tabs within the more info dialog ("Diet", "Tag", "Health", "Notes") that open
the dialog with that specific tab opened. These buttons are also disabled if there is no row selected in the
grid below to re-enforce to the user that they are related to the selected row. Ref #27682.
- Added ability to navigate the grids with keyboard arrow keys (up, down, left and right). Ref #27677.
-
The more info dialog is now pre-populated with data if there was data previously entered for the fish. Ref
#26253.
- Batch weights are now rounded to one decimal place. Ref #25990.
- Rows that have weights that have manually been cleared out are now included in batch weights. Ref #28579.
0.12.0 December 6, 2013
-
Duplicate station names are now allowed. Unique ids (GUID's) are used to identify them behind the scenes. Ref
#26528.
- Map cursor now changes to a "cross hair" cursor when dropping points on the map. Ref #28525.
- True/False drop downs have been changed to Yes/No. Ref #28523.
-
All fields, selected map points and grids are cleared when the event is submitted or the cancel button is
pressed. Ref #28370.
- Added dominant overstory and understory drop down values. Ref #28361.
- After creating a new station, a corresponding point is added to the main map and selected. Ref #28360.
- The selected station map marker now turns yellow.
-
Fixed validation bug with point definition boxes that was preventing them from turning red when invalid. Ref
#28242.
-
Up to 20 results are now shown in the stream search drop down menu. This seems to be OK for the streams that I
tested. Ref #27688.
-
Diet tab (more info dialog): Changed "Unidentified fish" to "Fish" and added a new field called "Fish Species"
which has the same drop down as the "Species Code" field in the catch grid. Ref #27687.
-
All drop downs now preserve the description value (as apposed to the code value) excluding "Species Code" and
"Length Type".
- Minor layout/heading cleanup.
- Fixed incorrect layout of grids introduced at 0.11.0.
- Removed type-ahead for station box since they can now be selected by clicking on the map.
0.11.0 November 29, 2013
- All numeric text inputs now show validation errors as the user types. Ref #26463
- Fixed bug that was causing a cell value to be lost when navigating back to that cell. Ref #27678.
-
Fixed bug that was preventing the user from successfully selecting a drop-down option by clicking on it. Ref
#27684.
- Adds blue markers for existing stations on maps. Ref #20323.
-
Updated the order of the Location tab to put the map first, then the station box, then the stream reach. Ref
#27679.
-
Moved main tab buttons and the submit/cancel buttons to the header. This makes them accessible at all time no
matter where you are on the page. Ref #27680.
0.10.0 November 8, 2013
- Added Habitat tab and wired to database.
- Upgraded the look-and-feel library (Bootstrap) to version 3.
- Upgraded comboboxes to work with Bootstrap v3.
0.9.0 September 17, 2013
- Added stream search box to both maps.
- Fixed bug related to switching raft/boat cathode type. (#26461)
- Upgraded Leaflet to 0.6.0.
0.8.0 September 3, 2013
- Fixed problems with data transfer to database. All data is now being submitted correctly to the database.
- Reports are now archived on the client side in case of problems on the server.
- Collection event dates are now submitted appropriately.
0.7.0 August 21, 2013
- Re-ordered tag form controls. Ref #25992.
- Added unit labels according to the changes made by Craig to the fields spreadsheet. Ref #26103.
-
Cathode diameter is now automatically cleared and disabled when "Boat" is selected as the Cathode type in the
Boat/Raft section on the Method tab. Ref #24794.
- Fixed label misalignment for backpacks, canoe/barges, and raft/boats. #26124.
- Finished wiring up more info dialog.
-
Complete reports can now be submitted to the database (except the Habitat tab which hasn't been implemented
yet).
0.6.0 July 18, 2013
- Added more info dialog to catch tab grid (not wired up to submit data to database yet). Ref #25757.
0.5.0 July 9, 2013
- Added Event Date field to location tab. Ref #23811.
- On successful submit, stream length and additional notes fields are cleared. Ref #20634.
- Method tab controls finalized and validating.
- Catch tab grid built (not wired up to submit data to database yet).
0.4.0 Nov 20, 2012
-
New collection events can now be submitted successfully and are being stored in the test database along with the
stations data.
- Added error reporter to most errors so that they are logged and an email is sent to the developer.
-
Added values for EVENT_DATE, GEO_DEF, and EVENT_ID for the sampling event feature. These are all values that are
automatically calculated behind the scenes and sent with the rest of the data to the server.
-
Added fields for stream length and additional location notes below the verify map. Stream length is
automatically filled in when defining the location using the Start, Distance & Direction method.
0.3.0 Nov 15, 2012
- You can now create new stations.
- Moved the Coordinate type buttons to a settings dialog toggled by a button in the header.
-
Added stream type drop down to new station dialog. This is automatically populated with the domain values for
this field in the geodatabase.
- Defining a location by waterbody id now works.
- Added "Settings" text to the settings dialog toggle button.
0.2.0 Oct 31, 2012
- Start | Distance | Direction location definition now works.
- ID location definition now works.
0.1.0 Oct 29, 2012
- Initial release.
- Select a station
- Defined start and end points and see validation errors.
- Verify geometry and see resulting stream segment.
- Submit the report actually adds data to the database.
- Cancel clears the report.
- Settings dialog with coordinate type toggle buttons.


Most Recent, newest first
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme
-
Massively Overpowered
LOTRO composer Chance Thomas loses sound company over ponzi scheme


to view carbonic anhydrase structure
Carbon dioxide (CO2) is a key metabolite in all living organisms. Carbon dioxide exists in equilibrium with bicarbonate (HCO3-), which is poorly soluble in lipid membranes compared to carbon dioxide; carbon dioxide can freely diffuse in and out of the cell, while bicarbonate must be transported. The conversion of bicarbonate to carbon dioxide facilitates its transport into the cell, while the conversion of carbon dioxide to bicarbonate helps trap the carbon dioxide in the cell. The interconversion of carbon dioxide and bicarbonate proceeds slowly at physiological pH, so organisms produce enzymes to speed up the process. Carbonic anhydrases are zinc-containing enzymes that catalyse the reversible reaction between carbon dioxide hydration and bicarbonate dehydration. Carbonic anhydrases have been found in all kingdoms of life. They have essential roles in facilitating the transport of carbon dioxide and protons in the intracellular space, across biological membranes and in the layers of the extracellular space; they are also involved in many other processes, from respiration and photosynthesis in eukaryotes to cyanate degradation in prokaryotes.
Carbonic anhydrase catalyses the following reaction:
H2O + CO2 ßà H+ + HCO3-
This reaction is ubiquitous in nature, involving the interchange of gaseous and ionic species crucial to a wide range of physiological and biochemical processes. The mechanism of action of the mammalian carbonic anhydrase has been studied in depth. The enzyme employs a two-step mechanism: in the first step, there is a nucleophilic attack of a zinc-bound hydroxide ion on carbon dioxide; in the second step, the active site is regenerated by the ionisation of the zinc-bound water molecule and the removal of a proton from the active site. The active site can exist in two forms: a high pH form that is active in the hydration of carbon dioxide and a low pH form that is active in the dehydration of bicarbonate.
Species can produce many different carbonic anhydrase isozymes, some of which act in the cytosol, while others are membrane-bound. For instance, in humans there are three cytosolic isozymes (I, II and III), five membrane-bound isozymes (IV, VII, IX, XII and XIV), a mitochondrial isozyme (V), and a secreted salivary isozyme (VI), as well as several related proteins that lack catalytic activity. Carbonic anhydrases are often arranged in clusters along membranes or localised in extracellular spaces, which may contribute to the ability of carbonic anhydrase to facilitate the intracellular diffusion of carbon dioxide and protons (H+). By increasing the movement of protons, carbonic anhydrase can dissipate intracellular pH gradients, thereby helping the cell to maintain a uniform cellular pH. The removal of protons is essential for several reactions within the cell, such as for the functioning of ATPases, which are inhibited by a build-up of protons; as a result, the inhibition of carbonic anhydrase could reduce muscle contractility and calcium handling. Carbonic anhydrases can also create localised gradients, which may aid in processes such as facilitated diffusion across a membrane.


{% extends "layout.html" %} {% block content %} {% include "includes/phase_banner_alpha.html" %} {{jobs.length}} jobs match your search Refine search {% for job in jobs %} {{job.title}} at {{job.hiringOrganization.name}}, salary from £{{job.minSalary}} {{job.responsibilities}} Apply now {% endfor %} {% endblock %}
Refine search
at {{job.hiringOrganization.name}}, salary from £{{job.minSalary}} {{job.responsibilities}} Apply now


Man shot and killed after armed group attacks Verulam community
by Kaveel SinghOne person was killed on Sunday after a group of armed men allegedly targeted the Canelands area in Verulam, north of Durban.
"A case of murder was opened at Verulam police station after a 30-year-old man was allegedly shot by unknown people. He sustained a gunshot wound on the chest and was declared dead at the scene," police spokesperson Colonel Thembeka Mbele said on Monday.
Reaction Unit SA (Rusa) head Prem Balram said they received several calls from residents of the Thunder Town area on Station Road, reporting shots being fired on the railway line behind their homes.
"Upon arrival, it was established that four security officers based at the train station noticed three individuals walking towards them. Two men suddenly drew firearms and without warning fired a volley of shots in their direction. The officers split up and took cover. Their attackers then fled without taking anything."
Balram said officers then went in search of the gunmen.
"While patrolling Station Road, Reaction officers noticed a group of people standing around an individual lying in the centre of the road. He had sustained a single gunshot wound to his chest and died at the scene."
The victim was thought to have left home to go to the shop.
"Events leading up to his death are unclear, however it is alleged that he may have been confronted and robbed by the suspects who shot him before they fled towards the train station where they also opened fire on security officers."


3 references to ProgressRecord
System.Management.Automation (3)
engine\serialization.cs (3)
4643
deserializer.ReadStartElement(SerializationStrings.
ProgressRecord
);
5275
SerializationStrings.
ProgressRecord
,
5276
SerializationStrings.
ProgressRecord
,


In this series of blog posts, I will be talking about Ansible. Ansible is a powerful automation tool that you can learn quickly.
When using Ansible, I have been constantly uneasy about how inventory is managed. If you feel the same, in this article I will try to explain how I structure my inventories and where I think it could be improved.
The Ansible documentation recommends to put servers in groups by type, like so:
mail.example.com [webservers] foo.example.com bar.example.com [dbservers] one.example.com two.example.com three.example.com
In your playbook you can then target specific parts to one group. For example your webservers will have different packages compared to your db servers. It also allows you to limit deployment to one group. For example with the –limit flag you can limit your deployment to just the dbservers.
An alternative approach I have been taking is to create seperate inventories for each environment. Like Production, UAT and Testing. For each environment I create an inventory like so:
[webservers] web-1-prd.example.com web-2-prd.example.com [dbservers] db-1-prd.example.com
UAT:
[webservers] web-1-uat.example.com web-2-uat.example.com [dbservers] db-1-uat.example.com
This means that when I run my Ansible command, I have a separate command for each environment. This means there is less of a chance of deploying to the wrong servers and I can deploy an entire environment all at once easily. Those commands would look like this:
ansible-playbook rails_stack.yml -i uat
ansible-playbook rails_stack.yml -i prod
The Ansible best practices document recommends this as well and naming your groups based on their location (data center).


How to Save Emails to Pocket In this post I share how I save email to my 'Pocket' so that I can make notes on them. This is very useful for various email courses or other email with valuable content.
My criteria for a tiny SaaS - Public Notes I have too many ideas. If these ideas were all great, this would be OK. Unfortunately, they aren’t. Many are bad ideas. The rest tend to be
Ruby vs Crystal Performance I’ve been hearing about the Crystal programming language here and there over the last couple of years but never had a chance to give it a look until yesterday. What is Crystal? It’s a statically type, compiled, object-oriented language with syntax heavily...
Presentation Rules – Jilles.net <p>Invariably my work requires to create and consume various presentations ofdiffering nature. I also spend a reason...
Building an easy on the eyes IKEA style blog, in no time, for free, again It's been over a year since I bought a new domain and redesigned my blog. I wrote a post about Medium…
Going serverless :: Aloïs Micard I used to manage a dozen VPS since many years: Zabbix, Gitlab/Gitlab CI, private docker registry, production environment (3 nodes docker swarm cluster), database server (MariaDB & MongoDB), blog server (running Ghost), logs collector (Graylog), etc&he...
How to be Extraordinarily Ordinary – The Blog of Joe Balcom Being ordinary is safe. It's easy. It’s firmly within your comfort zone. It is the status quo. No one questions you because you fit in. Be careful...


Calculation method
Karachi
Jafari
MWL
ISNA
Makkah
Egypt
Asr calculation
Standard
Hanafi
Midnight calculation
Standard
Shia
High latitude corrections
Angle based
Midnight rule
One-seventh rule
Prayer names
English
Arabic


I will be starting a series of blog posts around various topics in control theory, including optimal and robust control. The purpose is to teach myself these topics, and one effective way I have found to learn is to write. $ \newcommand{\abs}[1]{| #1 |} \newcommand{\ind}{\mathbf{1}} \newcommand{\norm}[1]{\lVert #1 \rVert} \newcommand{\ip}[2]{\langle #1, #2 \rangle} \newcommand{\R}{\mathbb{R}} \newcommand{\C}{\mathbb{C}} \newcommand{\T}{\mathsf{T}} \newcommand{\Proj}{\mathcal{P}} \newcommand{\Tr}{\mathrm{Tr}} \newcommand{\A}{\mathcal{A}} $
Setup
We start with the very basics. These notes are based on Boyd's EE363 notes. Consider the following discrete time linear dynamical system with state dimension $n$ and input dimension $m$, $$ \begin{align} x_{k+1} &= A x_{k} + B u_{k} \:, \:\: k = 0, 1, 2, ... \label{eq:lds} \end{align} $$ Above, $A \in \R^{n \times n}$ and $B \in \R^{n \times m}$. Notice that there is no observation $y_k$. In other words, we are assuming perfect state observation for now. In the next post, we will relax this with Kalman filtering.
The optimal control problem
The optimal control problem is as follows. Suppose we have positive semi-definite matrices $Q \in \R^{n \times n}$ and $R \in \R^{m \times m}$. Given an $x_0 \in \R^n$ and a horizon $T \geq 0$, our goal is to choose $u_0, u_1, ..., u_{T-1} \in \R^{m}$ such that the following function is minimized, $$ \begin{align} V(u_0, u_1, ..., u_{T-1}; x_0) = \sum_{k=0}^{T-1} (x_k^\T Q x_k + u_k^\T R u_k) + x_{T}^\T Q x_{T} \:, \:\: x_{k+1} = A x_{k} + B u_{k} \:. \label{eq:lqr_obj} \end{align} $$
Least squares and structured matrices
We now show that (perhaps unsurprisingly) the objective $\eqref{eq:lqr_obj}$ is just a large least squares problem. In doing so, we will reveal a certain structure of the problem, which hints at a more efficient solution.
The first step towards this is to unroll the recursion $\eqref{eq:lds}$, and show that $x_k$ is a linear function of the inputs $u_0, u_1, ..., u_{k-1}$ and the starting state $x_0$. The way I like to do this is to unroll it for a small number (we will do $k=3$), and then guess the form for general $k$. For $k=3$, we have $$ \begin{align*} x_{3} &= A x_{2} + B u_{2} \\ &= A(A x_{1} + B u_{1}) + B u_{2} \\ &= A^2 x_{1} + AB u_{1} + B u_{2} \\ &= A^2( A x_{0} + B u_{0} ) + AB u_{1} + B u_{2} \\ &= A^3 x_{0} + A^2 B u_{0} + AB u_{1} + B u_{2} \:. \end{align*} $$ From this, we can guess (and prove by induction if you really want) that $$ \begin{align} x_{k} = A^{k} x_0 + \sum_{j=0}^{k-1} A^{k-1-j} B u_j \:. \label{eq:lds_formula} \end{align} $$
Using $\eqref{eq:lds_formula}$, we can write (this is just the formula on page 10 of Boyd's notes) $$ \begin{align} \underbrace{\begin{bmatrix} x_0 \\ x_1 \\ x_2 \\ x_3 \\ \vdots \\ x_{T} \end{bmatrix}}_{\mathbf{x}} = \underbrace{\begin{bmatrix} 0 & 0 & 0 & 0 & \cdots & 0 \\ B & 0 & 0 & 0 & \cdots & 0 \\ AB & B & 0 & 0 & \cdots & 0 \\ A^2B & AB & B & 0 & \cdots & 0 \\ \vdots & \vdots & \vdots & \vdots & \ddots & \vdots \\ A^{T-1}B & A^{T-2}B & A^{T-3}B & A^{T-4} B & \cdots & B \end{bmatrix}}_{G} \underbrace{\begin{bmatrix} u_0 \\ u_1 \\ u_2 \\ u_3 \\ \vdots \\ u_{T-1} \end{bmatrix}}_{\mathbf{u}} + \underbrace{\begin{bmatrix} I \\ A \\ A^2 \\ A^3 \\ \vdots \\ A^{T} \end{bmatrix}}_{H} x_0 \:. \label{eq:relationship} \end{align} $$
It is worth a moment to pause and reflect on the structure of $G$. Note that $G$ is a special case of a Toeplitz matrix. Furthermore, $G$ reflects the causal nature of $\eqref{eq:lds}$.
We now proceed as follows. We write $V(u_0, u_1, ... u_{T-1}; x_0)$ in terms of the stacked column vectors $\mathbf{x}$ and $\mathbf{u}$, and then plug the relationship $\eqref{eq:relationship}$ between $\mathbf{x}$ and $\mathbf{u}$ in. It is not hard to see that $$ \begin{align*} &V(u_0, u_1, ... u_{T-1}; x_0) \\ &\qquad= \mathbf{x}^\T \mathrm{blkdiag}(\underbrace{Q, Q, ..., Q}_{T+1 \text{ times}}) \mathbf{x} + \mathbf{u}^\T \mathrm{blkdiag}(\underbrace{R, R, ..., R}_{T \text{ times}}) \mathbf{u} \\ &\qquad= (G \mathbf{u} + H x_0)^\T \mathrm{blkdiag}(Q, Q, ..., Q) (G \mathbf{u} + H x_0) + \mathbf{u}^\T \mathrm{blkdiag}(R, R, ..., R) \mathbf{u} \:. \end{align*} $$ This is simply a least squares problem, and solution(s) can be found by solving the linear system $$ (G^\T \mathrm{blkdiag}(Q, Q, ..., Q) G + \mathrm{blkdiag}(R, R, ..., R))\mathbf{u} = -G^\T \mathrm{blkdiag}(Q, Q, ..., Q) H x_0 \:. $$ If $R$ is positive definite, then the solution is unique. Ignoring $n, m$, the cost of solving this linear system is $O(T^3)$ which becomes intractable for large horizons. It turns out we can do much better.
Dynamic programming and cost-to-go
The key insight is to use dynamic programming. Moving forward, we will assume that $R$ is positive definite. We start by defining the following cost-to-go function $V_{t} : \R^{n} \longrightarrow \R$ for $t=0, 1, ...., T$ as $$ V_{t}(z) = \min_{u_{t}, u_{t+1}, ..., u_{T-1} \in \R^{m}} \sum_{k=t}^{T-1} (x_k^\T Q x_k + u_k^\T R u_k) + x_{T}^\T Q x_{T} \: : \: x_{t} = z, x_{k+1} = A x_{k} + B u_{k}, k=t, t+1, ..., T-1 \:. $$ The idea is we will relate $V_{t}(z)$ to $V_{t+1}(z)$, and along the way we will discover the optimal values for $u_t$. First, we take case of the base case $t=T$. Plugging in, we get that $$ V_{T}(z) = z^\T Q z \:. $$ There is nothing to solve for here. But we see that $V_{T}(z)$ is a positive semi-definite (PSD) quadratic function.
We will now proceed inductively, assuming that $V_{t+1}(z)$ is a PSD quadratic function and showing that $V_{t}(z)$ is itself PSD quadratic. In the process, we will derive the formulas for the optimal $u_{t}$'s. Since $V_{t+1}(z)$ is PSD quadratic, there is a symmetric PSD $n \times n$ matrix $P_{t+1}$ such that $V_{t+1}(z) = z^\T P_{t+1} z$. We therefore write $$ \begin{align*} V_{t}(z) &= \min_{u_t \in \R^{m}} z^\T Q z + u_t^\T R u_t + V_{t+1}(A z + B u_t) \\ &= \min_{u_t \in \R^{m}} z^\T Q z + u_t^\T R u_t + (A z + B u_t)^\T P_{t+1} (A z + B u_t) \:. \end{align*} $$ Taking the gradient of the RHS w.r.t. $u_t$ and setting it to zero, we get that $$ \begin{align*} u_t = -(R + B^\T P_{t+1} B)^{-1} B^\T P_{t+1} A z \end{align*} $$ Note that the matrix $R + B^\T P_{t+1} B$ is invertible because we assumed that $R$ is positive definite and $P_{t+1}$ is positive semi-definite by the inductive hypothesis.  But we still need to check that it is positive semi-definite. To do this, we first observe that for any $\varepsilon > 0$ we have $B^\T P_{t+1} B \succeq B^\T P_{t+1}(P_{t+1} + \varepsilon I)^{-1} P_{t+1} B$. By Schur complements, this is equivalent to, $$ \begin{align*} B^\T P_{t+1} B \succeq B^\T P_{t+1}(P_{t+1} + \varepsilon I)^{-1} P_{t+1} B &\Longleftrightarrow B^\T P_{t+1} B - B^\T P_{t+1}(P_{t+1} + \varepsilon I)^{-1} P_{t+1} B \succeq 0 \\ &\Longleftrightarrow \begin{bmatrix} P_{t+1} + \varepsilon I & P_{t+1} B \\ B^\T P_{t+1} & B^\T P_{t+1} B \end{bmatrix} \succeq 0 \:. \end{align*} $$ Sending $\varepsilon > 0$ and using the fact that the PSD cone is closed, we conclude that $$ \begin{align} \begin{bmatrix} P_{t+1} & P_{t+1} B \\ B^\T P_{t+1} & B^\T P_{t+1} B \end{bmatrix} \succeq 0 \:. \label{eq:gen_schur_complement} \end{align} $$ (Note that this last equation can also be derived from generalized Schur complements). Now, we are in position to claim that $P_{t}$ is positive semi-definite, since $$ \begin{align} P_{t+1} - P_{t+1} B (R + B^\T P_{t+1} B)^{-1} P_{t+1} \succeq 0 &\Longleftrightarrow \begin{bmatrix} P_{t+1} & P_{t+1} B \\ B^\T P_{t+1} & R + B^\T P_{t+1} B \end{bmatrix} \succeq 0 \nonumber \\ &\Longleftrightarrow \begin{bmatrix} 0 & 0 \\ 0 & R \end{bmatrix} + \begin{bmatrix} P_{t+1} & P_{t+1} B \\ B^\T P_{t+1} & B^\T P_{t+1} B \end{bmatrix} \succeq 0 \label{eq:ordering} \:. \end{align} $$ Since we assumed $R$ is positive definite , the latter condition clearly holds in view of $\eqref{eq:gen_schur_complement}$. Therefore, since $Q$ is positive semi-definite, $$ \begin{align*} P_{t} &= Q + A^\T P_{t+1} A - A^\T P_{t+1} B (R + B^\T P_{t+1} B)^{-1} B^\T P_{t+1} A \\ &= Q + A^\T (P_{t+1} - P_{t+1} B (R + B^\T P_{t+1} B)^{-1} B^\T P_{t+1}) A \succeq 0 \:. \end{align*} $$ The final inequaity holds since conjugation by $A$ preserves the PSD ordering established in $\eqref{eq:ordering}$.
The Ricatti solution
The calculations in the last section naturally suggest an algorithm for computing the optimal $u_0, u_1, ..., u_{T-1}$.
- Set $P_{T} = Q$.
- For $t = T-1, T-2, ..., 0$, compute $P_{t} = Q + A^\T P_{t+1} A - A^\T P_{t+1} B (R + B^\T P_{t+1} B)^{-1} B^\T P_{t+1} A$.
- For $t = 0, 1, ..., T-1$, compute $u_t = -\underbrace{(R + B^\T P_{t+1} B)^{-1} B^\T P_{t+1} A}_{K_t} x_t$, $x_{t+1} = A x_t + B u_t$.
We have shown that for any positive semi-definite quadratic cost, the optimal control policy is state feedback via $u_t = -K_t x_t$, where $K_t$ is computed above. Furthermore, we have constructed what appears to be a fixed point equation. Define the operator $\mathcal{D}$ as $$ \mathcal{D}(P) = Q + A^\T P A - A^\T P B (R + B^\T P B)^{-1} B^\T P A \:. $$ Our computations of $P_t$ appear to be (trying to) compute a fixed point $$ P = \mathcal{D}(P) \:. $$ Does this operator $\mathcal{D}$ have fixed points? If so, is there a unique fixed point? Is the fixed point a positive semi-definite matrix? If there is a fixed point, does it define a stabilizing controller once we compute the associated gain matrix $K$? These are all natural questions to ask.
Unfortunately, for reasons I do not fully understand, answering these questions in the discrete time case is a bit more involved than in the continuous case. (On the other hand, the derivations above were arguably easier in the discrete time than the continuous case, so we made a concious tradeoff). Nevertheless, we will attempt to give some partial answers in what follows. Before we can proceed, however, we make a small detour concerning the discrete Lyapunov operator.
Discrete Lyapunov operator
Given an $n \times n$ complex matrix $A$, define the discrete Lyapunov operator $\mathcal{L}_{A} : \C^{n \times n} \longrightarrow \C^{n \times n}$ as $$ \mathcal{L}_{A}(X) = A^* X A - X \:. $$ The operator $\mathcal{L}_{A}$ is clearly a linear operator. It is well known (see e.g. these notes) that $\mathcal{L}_{A}$ is an invertible operator iff $\lambda_i \overline{\lambda_j} \neq 1$ for all $1 \leq i, j \leq n$, where $\lambda_i$ are the eigenvalues of $A$. Hence, if $A$ is stable, then $\mathcal{L}_{A}$ is injective, a fact we will use later on.
The discrete algebraic Ricatti equation (DARE)
The following derivations follow fairly closely Chapter 21 of Zhou, Doyle, and Glover's Robust and Optimal Control. However, I try to fill in some of the details. This construction is quite clever (at least to me), and it is not obvious to me how one would come up with this (maybe it is more obvious upon further study).
The first step is to rewrite the Ricatti equation to be slightly easier to manipulate. We note that $$ R^{-1} B^\T(I + P B R^{-1} B^\T)^{-1} = R^{-1} (I + B^\T P B R^{-1})^{-1} B^\T = (R + B^\T X B)^{-1} B^\T \:. $$ This identity allows us to write $$ \mathcal{D}(P) = Q + A^\T P A - A^\T P B R^{-1} B^\T(I + P B R^{-1} B^\T)^{-1} P A \:. $$ We now call the matrix $M = B R^{-1} B^\T$ (observe $M = M^\T$) and write $$ \mathcal{D}(P) = Q + A^\T P A - A^\T P M (I + P M)^{-1} P A \:. $$ We suppose that $A$ is invertible (these results are supposed to be generalizable beyond the case when $A$ is invertible but I have not worked out the details yet), and define the following $2n \times 2n$ symplectic matrix with respect to the $2n \times 2n$ matrix $J$, where $$ S = \begin{bmatrix} A + M A^{-\T} Q & - MA^{-\T} \\ -A^{-\T} Q & A^{-\T} \end{bmatrix} \:, \:\: J = \begin{bmatrix} 0 & -I \\ I & 0 \end{bmatrix} \:. $$ To check that $S$ is indeed symplectic, we compute $$ \begin{align*} S^\T J S &= \begin{bmatrix} A^\T + Q A^{-1} M & - QA^{-1} \\ -A^{-1} M & A^{-1} \end{bmatrix} \begin{bmatrix} 0 & -I \\ I & 0 \end{bmatrix} \begin{bmatrix} A + M A^{-\T} Q & - MA^{-\T} \\ -A^{-\T} Q & A^{-\T} \end{bmatrix} \\ &= \begin{bmatrix} A^\T + Q A^{-1} M & - QA^{-1} \\ -A^{-1} M & A^{-1} \end{bmatrix} \begin{bmatrix} A^{-\T} Q & - A^{-\T} \\ A + M A^{-\T} Q & - M A^{-\T} \end{bmatrix} \\ &= \begin{bmatrix} 0 & -I \\ I & 0 \end{bmatrix} = J \:. \end{align*} $$ Since $S$ is symplectic, it is invertible and its inverse is $S^{-1} = J^{-1} S^\T J$. This is easy to see, since $J^{-1} S^\T J S = J^{-1} J = I$. We now state another fact for symplectic matrices. If $\lambda \in \C$ is an eigenvalue of $S$, then $\lambda^{-1} \in \C$ is also an eigenvalue of $S$ ($\lambda \neq 0$ since $S$ is invertible). To see this, let $S v = \lambda v$ for some $\lambda \neq 0$. Then $J v = S^\T J S v = \lambda S^\T J v$. This implies that $S^\T (J v) = \lambda^{-1} (J v)$, and hence since $S$ and $S^\T$ have the same eigenvalues, $\lambda^{-1}$ is an eigenvalue of $S$ as well. An immediate consequence of this is that if $S$ has no eigenvalues on the unit circle, then $S$ has exactly $n$ eigenvalues $\abs{\lambda} < 1$ and $n$ eigenvalues $\abs{\lambda} > 1$. Define the following subspace $$ N = \mathrm{span}\{ v \in \C^{2n} : Sv = \lambda v, \abs{\lambda} < 1 \} \:. $$ We just argued that $\mathrm{dim}(N) \leq n$. Hence, there exists a matrix $T \in \C^{2n \times n}$ such that $\mathcal{R}(T) = N$. Partition $T$ as $$ T = \begin{bmatrix} T_1 \\ T_2 \end{bmatrix} \:, \:\: T_1, T_2 \in \C^{n \times n} \:. $$ Let us now make the assumption that $T_1$ is invertible. Theorem 21.7 of Zhou, Doyle and Glover states that $T_1$ is invertible when $(A, B R^{-1} B^\T)$ is stabilizable and $(Q, A)$ has no unobservable modes on the unit circle; we will not prove this. Now under this assumption, we set $P = T_2 T_1^{-1}$. We will now argue that $P = \mathcal{D}(P)$.
$P$ is symmetric: We first argue why $P$ is symmetric. The starting point is to observe that $$ T_1^* P T_1 = T_1^* T_2 \:. $$ Hence, $P$ is symmetric iff $T_1^* T_2$ is Hermitian. Now, since $T$ contains columns of eigenvectors with stable eigenvalues, $ST = T \Lambda$ where $\Lambda$ is a stable diagonal $n \times n$ matrix. We now take advantage of the fact that $S$ is symplectic, and compute $$ \begin{align*} \Lambda^* T^* J T \Lambda = \Lambda^* T^* J S T = T^* S^\T J S T = T^* J T &\Longleftrightarrow \Lambda^* (T^* J T) \Lambda - (T^* J T) = 0 \\ &\Longleftrightarrow \mathcal{L}_{\Lambda}(T^* J T) = 0 \\ &\Longleftrightarrow T^* J T = 0 \:. \end{align*} $$ The last equivalence follows from the fact that $\Lambda$ is stable and hence we know that the Lyapunov operator is injective. Expanding out the last fact, $$ 0 = \begin{bmatrix} T_1^* & T_2^* \end{bmatrix} \begin{bmatrix} 0 & -I \\ I & 0 \end{bmatrix} \begin{bmatrix} T_1 \\ T_2 \end{bmatrix} = \begin{bmatrix} T_1^* & T_2^* \end{bmatrix} \begin{bmatrix} - T_2 \\ T_1 \end{bmatrix} = - T_1^* T_2 + T_2^* T_1 \Longleftrightarrow T_1^* T_2 = T_2^* T_1 \:, $$ and hence we have shown that $T_1^* T_2$ is Hermitian, as desired.
$P$ solves the fixed point $\mathcal{D}(P) = P$: The starting point of this analysis is to note the identity $$ S \begin{bmatrix} I \\ P \end{bmatrix} = \begin{bmatrix} I \\ P \end{bmatrix} T_1 \Lambda T_1^{-1} \Longrightarrow \begin{bmatrix} -P & I \end{bmatrix} S \begin{bmatrix} I \\ P \end{bmatrix} = 0 \:. $$ Expanding out the RHS identity, $$ \begin{align} 0 &= \begin{bmatrix} -P & I \end{bmatrix} S \begin{bmatrix} I \\ P \end{bmatrix} \nonumber \\ &= -P A - P M A^{-\T} Q + P M A^{-\T} P - A^{-\T} Q + A^{-\T} P \nonumber \\ &= -P A + (A^{-\T} + P M A^{-\T})(P - Q) \nonumber \\ &= -P A + (I + P M) A^{-\T} (P - Q) \:. \label{eq:ident_one} \end{align} $$ Now observe that, $$ \begin{align*} P - PM(I + PM)^{-1} P &= (I+PM)(I+PM)^{-1} P - PM(I + PM)^{-1} P \\ &= (I + PM - PM)(I + PM)^{-1} P = (I + PM)^{-1} P \:. \end{align*} $$ Hence, $$ \begin{align} A^\T P A - A^\T P M(I + PM)^{-1} P A = A^\T (I + PM)^{-1} P A \:. \label{eq:ident_two} \end{align} $$ Suppose that $I + PM$ is invertible. Then, combining $\eqref{eq:ident_one}$ and $\eqref{eq:ident_two}$, $$ \begin{align*} (I + PM)^{-1} PA = A^{-\T} (P-Q) &\Longleftrightarrow Q + A^\T (I + PM)^{-1} PA = P \\ &\Longleftrightarrow Q + A^\T P A - A^\T P M(I + PM)^{-1} P A = P \\ &\Longleftrightarrow \mathcal{D}(P) = P \:. \end{align*} $$ It remains to prove that $I + PM$ is invertible. Let $v \in \C^{n}$ and consider all $v$'s that satisfy $$ v^* (I + PM) = 0 \:. $$ Using $\eqref{eq:ident_one}$, $$ 0 = -v^* PA + v^* (I + PM) A^{-\T}(P - Q) = -v^* PA \Longleftrightarrow v^* P = 0 \:. $$ The last equivalence holds since we assumed $A$ is invertible. But then we have that $v^* (I + PM) = v^* + v^* P M = 0$, and hence $I + PM$ is invertible. This concludes the argument that $P$ solves the fixed point.


Welcome to the Kubernetes sig-cli contributing guide. We are excited about the prospect of you joining our community!
We strongly recommend you to understand the main Kubernetes Contributor Guide and adhere to the contribution rules (specially signing the CLA).
You can also check the Contributor Cheat Sheet, with common resources for existing developers.
The process for contributing code to Kubernetes via SIG-CLI community.
Please be aware that all contributions to Kubernetes require time and commitment from project maintainers to direct and review work. This is done in additional to many other maintainer responsibilities, and direct engagement from maintainers is a finite resource.
This is important.
Learn about using kubectl with Kubernetes in the Kubernetes Basics Tutorial.
Learn about managing configuration in the kubectl docs.
Determine in what capacity you are looking to contribute:
Who is this for?
Contributors looking to engage with the SIG cli community for a sustained period of time and looking to build working relationships with existing members. Route to becoming a SIG cli member as a reviewer or approver.
How does it work?
Work items come from a backlog of groomed items provided by SIG cli community members. Each items has a stake holder willing to provide limited direction to contributors working on it. Contributors typically need to put in 10x the time per-issue as the maintainers providing direction. Contributors are expected to learn and do research to complete the task independently with only periodic direction (~weekly).
What is expected of contributors?
Contributors are expected to make progress on items weekly and provide periodic updates to any issue they are working on. Contributors are expected exercise ownership of their code by fixing bugs that are discovered.
Who is this for?
Contributors that are looking to contribute only 1 or 2 items, or have a specific issue they would like to like resolve and are willing to contribute the solution.
How does it work?
Contributors are free to pick up any work items that they like. Maintainers will be focused on directing contributors working on Guided items, so contributors picking up non-Guided items will have almost no direction or support from maintainers.
What is expected of contributors?
Contributions must be relatively small, simple, well documented and well tested. Since maintainers will need to own any code for these contributions, these should be very limited in scope and contain minimal risk (e.g. simple regression fixes, improved documentation, improved testing).
kubectl
forkMake sure you are ready to immediately get started before you claim any piece of work.
kubectl hello-world
: print “Hello World”kubectl hello-kubernetes -f file
: Print “Hello <kind of resource> <name of resource>“kubectl hello-kubernetes type/name
: Print “Hello <kind of resource> <name of resource> <creation time>“Note: Consider publishing your command to a fork so a maintainer can look at it.
Pick up an issue from the backlog by commenting on the issue that you would like to work on it.
Be sure to mention the author of the issue as well as the SIG cli members @seans3
and @mengqiy
.
Using the following comment will make it easier for us to search for issues folks want to have assigned to them:
cc @seans3 @mengqiy I would like to take this
Note: Don’t do this unless you will start work on the issue within a few days of being assigned.
Note: GitHub only allows issues to be assigned to GitHub accounts that are part of the organization.
Picking your first issue
For your first issue, we recommend picking an issue labeled with “good first issue” from the issue backlog.
Picking the right size of issue
Be sure to pick up an issue that is appropriate to the time you are able to commit. We recommend first time contributors start with small or medium issues.
Following are very rough estimates, but are best effort only. They assume you have a development environment already set up and are able to build a kubectl binary and use it against a cluster. These estimates assume some knowledge of Go.
size/S
size/M
size/L
size/XL
Meta/Umbrella issues may have multiple components. By signing up for a Meta/Umbrella issue, you are only committing to one piece of it. Let the issue author know when you have completed some piece of it, and if you would like to continue working on it, or have it unassigned.
Picking the right kind of issue
Guided issues have a type defining the type of work to be done. Pick up an issue that fits your experience level and interest. Documentation and test-coverage issues typically are smaller in scope and easier to complete than features and cleanup issues.
type/code-cleanup
type/code-documentation
doc.go
with package overview and examples or add code comments to document
existing types and functions.type/code-feature
type/code-test-coverage
Provide periodic status updates
Once you have requested an issue and it has been accepted, you will be expected to provide periodic updates to it. Do update the issue with your status at least every week, and publish your work to a fork so the community can see your progress and provide early feedback.
If you find the issue is too challenging, time consuming, or you are no longer able to work on it, this is perfectly acceptable and please let the issue author know. If you like, you may pick up a different issue immediately or sometime in the future.
Summary:
@seans3
and @mengqiy
.
Expect a response within 2 days.Engage with the SIG cli community! Let us know who you are and how things are going!
Fill out the about me form so we know a bit about you and can direct your work accordingly.
Message the cli mentors googlegroup and let them know you filled out the form and are looking to get started.
In slack (signup here), @mention a lead and ask if there are any issues you could pick up, or let them know what you are working on.
Attend a sig-cli meeting and introduce yourself and what you are working on.
The sig-cli community page lists sig-cli leads, channels of communication, and group meeting times.
Once you have made several contributions, you may want to start developing features that you come up with. This section is about how to propose new features and get them accepted.
New contributors: Please start by adopting an existing issue.
A feature request is an issue mentioning @kubernetes/sig-cli-feature-requests
.
To encourage readership, the issue description should concisely (2-4 sentence) describe the problem that the feature addresses.
Working on a feature without getting approval for the user experience and software design often results in wasted time and effort due to decisions around flag names, command names, and specific command behavior.
To minimize wasted work and improve communication across efforts, the user experience and software design must be agreed upon before any PRs are sent for code review.
New contributors: Please start by adopting an existing issue.
A design proposal is a single markdown document in the design repo that follows the design template.
To make one,
- Prepare the markdown document as a PR to that repo.
- Avoid Work In Progress (WIP) PRs (send it only after
you consider it complete).
- For early feedback, use the email discussion group.
- Mention @kubernetes/sig-cli-proposals
in the description.
- Mention the related feature request.
Expect feedback from 2-3 different sig-cli community members.
Incorporate feedback and comment PTAL
.
Once a lead has agreed (via review commentary) that design and code review resources can be allocated to tackle the proposal, the details of the user experience and design should be discussed in the community.
This step is important; it prevents code churn and thrashing around issues like flag names, command names, etc.
It is normal for sig-cli community members to push back on feature proposals. sig-cli development and review resources are extremely constrained. Community members are free to say
The proposal can be merged into the design repo after leads approval and discussion as a meeting agenda item.
Then coding can begin.
Contributors can begin implementing a feature before any of the above steps have been completed, but should not send a PR until the design proposal has been merged.
See the development guide for instructions on setting up the Kubernetes development environment.
Implementation PRs should
- mention the issue of the associated design proposal,
- mention @kubernetes/sig-cli-pr-reviews
,
- include tests.
Small features and flag changes require only unit/integration tests, while larger changes require both unit/integration tests and e2e tests.
Leads need your help to ensure that progress is made to get the feature into a release.
While working on the issue, leave a weekly update on the issue including:
Let users know about cool new features by updating user facing documentation.
Depending on the contributor and size of the feature, this may be done either by the same contributor that implemented the feature, or another contributor who is more familiar with the existing docs templates.
Several weeks before a Kubernetes release, development enters a stabilization period where no new features are merged. For a feature to be accepted into a release, it must be fully merged and tested by this time. If your feature is not fully complete, including tests, it will have to wait until the next release.
If an issue isn’t getting any attention and is unresolved, mention
@kubernetes/sig-cli-bugs
.
Highlight the severity and urgency of the issue. For severe issues escalate by contacting sig leads and attending the meeting.
If an issue isn’t getting any attention and is unresolved, mention
@kubernetes/sig-cli-feature-requests
.
If a particular issue has a high impact for you or your business, make sure this is clear on the bug, and reach out to the sig leads directly. Consider attending the sig meeting to discuss over video conference.
It may happen that your PR seems to be stuck without clear actionable feedback for a week or longer. A PR associated with a bug or design proposal is much less likely to be stuck than a dangling PR.
However, if it happens do the following:
@kubernetes/sig-cli-pr-reviews
and ask for attention.PTAL
.If you are still not able to get any attention after a couple days, escalate to sig leads by mentioning them.
It may happen that your design doc gets stuck without getting merged or additional feedback. If you believe that your design is important and has been dropped, or it is not moving forward, please add it to the sig cli bi-weekly meeting agenda and mail the group saying you’d like to discuss it.
See the sig-cli community page for points of contact and meeting times:
@{any lead}
solicit opinion or advice from leads.@kubernetes/sig-cli-bugs
sig-cli centric bugs.@kubernetes/sig-cli-pr-reviews
triggers review of code fix PR.@kubernetes/sig-cli-feature-requests
flags a feature request.@kubernetes/sig-cli-proposals
flags a design proposal.


Source code
GrapheneOS is an open source project with an open development process.
The GrapheneOS sources are hosted in the GrapheneOS organization on GitHub. Since there are many repositories, this page aims to provide a guide for it. See the reporting issues section on the contact page for an comparable overview of where issues should be filed.
GrapheneOS
The operating system source tree includes hundreds of repositories. Many of these are only used for debugging, testing or development and are not actually part of what gets used for building a production release. The manifest repository references all of these. Most of these are used unmodified from the Android Open Source Project (AOSP). A few dozen of the repositories including most of the core OS are either forked from AOSP or are unique to GrapheneOS.
The operating system has a unified build system, but some components like Chromium are too complex to fit into it so they're included as prebuilts instead of porting them to the AOSP build system. This is also done for developer convenience and bootstrapping, to avoid needing to build all the native / cross-compilation toolchains for each host and target platform combination, etc. The prebuilts can all be built from source if desired. The build instructions will be expanded to cover all of this in the future.
For a full list of the repositories in the OS source tree, look at the default.xml list in the manifest repository.
GrapheneOS forks of AOSP repositories:
- device_common
- device_generic_goldfish
- device_google_barbet
- device_google_bonito
- device_google_bonito-sepolicy
- device_google_bramble
- device_google_coral
- device_google_coral-sepolicy
- device_google_crosshatch
- device_google_crosshatch-sepolicy
- device_google_gs101
- device_google_gs101-sepolicy
- device_google_raviole
- device_google_redbull
- device_google_redbull-sepolicy
- device_google_redfin
- device_google_sunfish
- device_google_sunfish-sepolicy
- kernel_configs
- platform_art
- platform_bionic
- platform_bootable_recovery
- platform_build
- platform_build_soong
- platform_development
- platform_external_android-nn-driver
- platform_external_armnn
- platform_external_conscrypt
- platform_frameworks_base
- platform_frameworks_ex
- platform_frameworks_libs_systemui
- platform_frameworks_native
- platform_frameworks_opt_net_wifi
- platform_hardware_google_pixel-sepolicy
- platform_libcore
- Manifest for OS repositories
- platform_packages_apps_Bluetooth
- platform_packages_apps_Calendar
- platform_packages_apps_CarrierConfig
- platform_packages_apps_Contacts
- platform_packages_apps_DeskClock
- platform_packages_apps_Dialer
- platform_packages_apps_Gallery2
- platform_packages_apps_Launcher3
- platform_packages_apps_Nfc
- platform_packages_apps_Messaging
- platform_packages_apps_QuickSearchBox
- platform_packages_apps_Settings
- platform_packages_apps_SettingsIntelligence
- platform_packages_apps_ThemePicker
- platform_packages_apps_WallpaperPicker2
- platform_packages_inputmethods_LatinIME
- platform_packages_modules_Connectivity
- platform_packages_modules_NetworkStack
- platform_packages_modules_Permission
- platform_packages_modules_Wifi
- platform_packages_providers_DownloadProvider
- platform_system_bt
- platform_system_core
- platform_system_extras
- platform_system_netd
- platform_system_sepolicy
Repositories added by GrapheneOS:
- adevtool
- android-prepare-vendor
- branding
- device_google_barbet-kernel
- device_google_blueline-kernel
- device_google_bonito-kernel
- device_google_bramble-kernel
- device_google_coral-kernel
- device_google_crosshatch-kernel
- device_google_redfin-kernel
- device_google_sunfish-kernel
- hardened_malloc
- kernel-manifest-raviole
- kernel_common_5.10
- kernel_google_barbet
- kernel_google_barbet_arch_arm64_boot_dts_vendor
- kernel_google_barbet_drivers_staging_qcacld-3.0
- kernel_google_barbet_teckpack_audio
- kernel_google_coral
- kernel_google_coral_drivers_staging_qcacld-3.0
- kernel_google_coral_drivers_input_touchscreen_fts_touch_s5
- kernel_google_coral_teckpack_audio
- kernel_google_crosshatch
- kernel_google_crosshatch_drivers_staging_qcacld-3.0
- kernel_google_crosshatch_teckpack_audio
- kernel_google_raviole
- kernel_google_redbull
- kernel_google_redbull_arch_arm64_boot_dts_vendor
- kernel_google_redbull_drivers_staging_qcacld-3.0
- kernel_google_redbull_teckpack_audio
- Apps prebuilt (platform_external_Apps)
- Auditor prebuilt (platform_external_Auditor)
- GrapheneOS Camera app (platform_external_Camera)
- PDF Viewer prebuilt (platform_external_PdfViewer)
- GrapheneOS fork of the open source Talkback accessibility service
- platform_external_seedvault
- Vanadium prebuilt (platform_external_vanadium)
- platform_packages_apps_ExactCalculator
- platform_packages_apps_SetupWizard
- OS update client (platform_packages_apps_Updater)
- platform_themes
- raviole-state
- script
Standalone apps
These are standalone app projects developed by GrapheneOS and included in the OS. This does not include the many apps included by AOSP without modifications by GrapheneOS or with only minor modifications.
Services
- infrastructure: Shared service infrastructure
- AttestationServer: attestation.app remote attestation service
- grapheneos.org: Main website
- releases.grapheneos.org: OS update service and app repository
- apps.grapheneos.org: App repository (extends releases.grapheneos.org)
- grapheneos.network: Connectivity check / time service
- mail.grapheneos.org: Mail service
- ns1.grapheneos.org: DNS service
Utilities
- tls-pinning: Utilities for setting up conservative non-leaf TLS pinning with backup pins
- branding-tools: Scripting for generating branding
- AttestationSamples: Auditor attestation samples
Archive
An archive of legacy repositories is available via the GrapheneOS Archive organization. This only covers repositories archives after renaming the project to GrapheneOS. Earlier code is mostly not available via GitHub anymore due to the unfortunate events leading to the rename of the project.


Vietnam
- Vietnam is the world’s leading exporter of cashew nuts and black pepper.
- The world’s second largest caves, the Son Doong caves are situated in Vietnam. The cave is so big that a Boeing 747 could fly through its largest cavern.
- Motorbikes are the most common form of transport in Vietnam.
- Snake wine is a common drink in Vietnam that is said to provide health and vitality to the person drinking it.
- Approximately 86% of the country's residents are Vietnamese. There are over 50 other minority groups that reside in Vietnam.
Cambodia
- The largest religious structure ever built is Angkor Wat (City Temple) in Cambodia. The site measures a massive 1,626,000m2 and was built by the Khmer King Suryavarman II from 1113-50 to honor the Hindu god Vishnu.
- Cambodia’s flag is the only one in the world to feature a building.
- You’ll find the largest freshwater lake in Southeast Asia in Cambodia.
- Evidence from carbon dating suggests that Cambodia was inhabited as early as 4000 B.C.
- Unlike most other cultures, Cambodians do not celebrate birthdays. In fact, many older people may not know the exact date of their birth.
Thailand
- The Orchid is Thailand’s national flower.
- The country is made up of almost 1,500 islands.
- The Mekong river is home to over 1,300 species of fish.
- Thailand is one of the most visited countries in the world.
- Thailand used to be called Siam.
Laos
- Laos is the only landlocked country in the whole of Southeast Asia.
- Laos is home to the largest waterfall in Southeast Asia.
 Over two billion tons of bombs were dropped in Laos during the Vietnam War.
- The official language of Laos is Lao, which sounds similar to Thai. Many of the older generation speak French, while the younger generation speak English as well as their native languages.
- Laos’ biggest agricultural export is coffee.


Town to town and up and down the dial said californey is the place
Collaboratively administrate empowered markets via plug-and-play networks.
Dynamically procrastinate B2C users after installed base benefits. Dramatically visualize customer directed convergence without revolutionary ROI.
Dynamically procrastinate B2C users after installed base benefits. Dramatically visualize customer directed convergence without revolutionary ROI.
Dynamically procrastinate B2C users after installed base benefits. Dramatically visualize customer directed convergence without revolutionary ROI.
Globally incubate standards compliant channels before scalable benefits.
Didn't need no welfare states. Everybody pulled his weight. Gee our old Lasalle ran great. Those were the days. Then one day he was shootin' at some food and up through the ground came a bubblin' crude. Oil that is--In a freak mishap Ranger 3 and its pilot Captain William Buck Rogers are blown out of their trajectory into an orbit which freezes his life support systems.
Michael Knight a young loner on a crusade to champion the cause of the innocent. The helpless. The powerless in a world of criminals who operate above the law. Just sit right back and you'll hear a tale a tale of a fateful trip that started from this tropic port aboard this tiny ship.
Michael Knight a young loner on a crusade to champion the cause of the innocent. The helpless. The powerless in a world of criminals who operate above the law. Just sit right back and you'll hear a tale a tale of a fateful trip that started from this tropic port aboard this tiny ship.
Didn't need no welfare states. Everybody pulled his weight. Gee our old Lasalle ran great. Those were the days. Then one day he was shootin' at some food and up through the ground came a bubblin' crude. Oil that is--In a freak mishap Ranger 3 and its pilot Captain William Buck Rogers are blown out of their trajectory into an orbit which freezes his life support systems.
Didn't need no welfare states. Everybody pulled his weight. Gee our old Lasalle ran great. Those were the days. Then one day he was shootin' at some food and up through the ground came a bubblin' crude. Oil that is--In a freak mishap Ranger 3 and its pilot Captain William Buck Rogers are blown out of their trajectory into an orbit which freezes his life support systems.
Michael Knight a young loner on a crusade to champion the cause of the innocent. The helpless. The powerless in a world of criminals who operate above the law. Just sit right back and you'll hear a tale a tale of a fateful trip that started from this tropic port aboard this tiny ship.
Town to town and up and down the dial said californey is the place
Quickly maximize timely deliverables for real-time schemas. Dramatically maintain Dramatically maintain
Completely synergize resource sucking relationships well premier niche markets Professionally
Objectively innovate empowered manufactured products whereas parallel platforms. Holisticly
Proactively envisioned multimedia based expertise and cross-media growth strategies. Seamlessly


Process¶
-
class
support.trifeni.trifeni.util.
Process
(name='', pid=0, ps_line=None, command_name='ssh')¶ Bases:
object
Class representing a basic process, with name and pid. A Process object is used to represent an already running process. To spawn a new process, use subprocess.subprocess.Popen.
-
name
¶ The name of the process
- Type
str
-
pid
¶ The process ID
- Type
int
Methods Summary
kill
()process_ps_line
(ps_line, command_name)Given a line from the output of ps x, get the name and pid of the process.
Methods Documentation
-
kill
()¶
-
process_ps_line
(ps_line, command_name)¶ Given a line from the output of ps x, get the name and pid of the process. Returns:
-


--- title: Model Interpretability keywords: fastai sidebar: home_sidebar summary: "Recipes for Model Interpretability" description: "Recipes for Model Interpretability" nb_path: "nbs/04_model_validation/model_interpretability.ipynb" ---
import xgboost
import shap
shap.initjs()
# train an XGBoost model
X, y = shap.datasets.boston()
model = xgboost.XGBRegressor().fit(X, y)
# explain the model's predictions using SHAP
# (same syntax works for LightGBM, CatBoost, scikit-learn, transformers, Spark, etc.)
explainer = shap.Explainer(model)
shap_values = explainer(X)
# visualize the first prediction's explanation
shap.plots.waterfall(shap_values[0])


Naga Siren
Tips
- Mirror Image can purge all the debuffs that a Manta would (besides Silences, obviously). Look at the
lane you're up against to see if an early Mirror Image could save your skin (like for Open Wounds or
Grave Chill). Mirror Image's split time also allows you to be invulnerable when projectile spells like
Wraith King or Sven's stuns hit.
- Send a unified move command (look in your options to find out what the key modifier is, by default it's
CTRL) after you split otherwise it's super obvious which Naga Naga Naga Naga is 100% Naga.
- Although couriers possess an unparalleled understanding on the intricacies of space and time, they are
like dolphins and get caught in those six-pack plastic can things all the time. Ensnare will bind both
walking and flying couriers.
- After you hit 6 and you're quietly farming, you should always try to keep at least 175 mana in the bank.
100 for the Song, 75 for the TP.
- If you aren't partied up in a 5 stack, just use your ult defensively. "Buuuut moooom, all the other
heroes get to press R in a team fight." "Maybe when you're older, Slithice. Why can't you be like that
nice boy Terrorblade and use your ult situationally?"
- You didn't listen to me, did you. You used it. See, Naga, this is why we can't trust you... Now look.
Everyone is shuffling around awkwardly on your team because they're both seething with rage and because
they can't tell if you want to commit to this failed fight or not. Hey. Hey, it's okay. Just press R
again. Yeah that's right, you can cancel your ult. You can just act like it was a misclick.
- Supposing you DO have a group of teammates who can take advantage of Song, here are some notable
interactions with it. Razor - Sleep doesn't stop Static Link. Undying - Zombies continue
to spawn on sleeping enemies. Warlock - Channel a fat Upheaval during the Sleep. Dazzle -
Weave can hit Sleeping enemies and will continue to tick during the Sleep. Omniknight - You can
offensively Repel one enemy to bring them out of Sleep.
- If an enemy activated a BKB in a team fight and there aren't any huge allied spells being thrown out,
you can try to isolate them with Song.
- Enemy structures are invulnerable during Song, but allied structures aren't. This allows you to get
uncontestable and rage inducing denies on towers.
- If you're TPing in to save teammates during a dive, consider starting the Song before you begin
channeling your TP.
- There aren't many situations in which you want to use all 7 seconds of your ult. If you catch someone
out with it, cancel it as soon as people are in position rather than buying the enemy team even more
time to get over there.
- Roshan is deaf. Sing near Rosh to quickly steal the kill+Aegis from the enemy, or to allow you to finish
Rosh without the enemy team causing a ruckus in the pit.
Counters
- Be wary of activating any sort of spell immunity before Naga uses Sleep, otherwise you might be setting
yourself up to die before the team fight even starts.
- Glyph makes towers immune to Sleep, allowing them to continue firing.
- Ensnare will interrupt any channels, reveal you if you're invis, disable you from blinking, and go
through spell immunity.
- Ensnare is dispellable by items like Diffusal Blade, Guardian Greaves, Eul's, Lotus Orb or Manta
Style.


Reproducible SCI-F Apps¶
Why do we need SCI-F?¶
The Scientific Filesystem (SCI-F) provides a consistent and modular method to create
containers. The SCI-F makes some assumptions about how the container will be created. By adhering to with the SCI-F format containers can bemore more reproducible.
For example, installing a set of
libraries, defining environment variables, or adding labels that
belong to application foo
makes a strong assertion that those dependencies belong
to foo
. When I run foo
, I can be confident that the container is running
in this context, meaning with foo
’s custom environment, and with foo
’s libraries
and executables on the path. This approach is different from
serving many executables in a single container that may have no way to know which application is associated with the container’s
intended functions. This documentation will walk through some
rationale, background, and examples of the SCI-F integration for
Singularity containers. For other examples (and a client that works
across container technologies) see the the scientific filesystem.
To start, let’s take a look at this series of steps to install dependencies for software foo and bar.
%post
# install dependencies 1
# install software A (foo)
# install software B (bar)
# install software C (foo)
# install software D (bar)
The creator may know that A and C were installed for foo
and B and D for bar
,
but down the road, when someone discovers the container, if they can
find the software at all, the intention of the container creator would
be lost. As many are now, containers without any form of internal
organization and predictability are black boxes. We don’t know if some
software installed to /opt
, or to /usr/local/bin
, or to their custom favorite folder /code
. We
could assume that the creator added important software to the path and
look in these locations, but that approach is still akin to fishing in a
swamp. We might only hope that the container’s main function, the
Singularity runscript, is enough to make the container perform as
intended.
Mixed up Modules¶
If your container truly runs one script, the traditional model of a
runscript fits well. Even in the case of having two functions like foo
and bar
you probably have something like this.
%runscript
if some logic to choose foo:
check arguments for foo
run foo
else if some logic to choose bar:
run bar
and maybe your environment looks like this:
%environment
BEST_GUY=foo
export BEST_GUY
%environment
BEST_GUY=foo
BEST_GUY=bar
export BEST_GUY
You obviously can’t have them at separate times. You would have to source some custom environment file (that you make on your own) and it gets confusing with issues of using shell and sourcing for the container. We don’t know who the best guy is! You probably get the general idea. Without consistent internal organization and modularity the following may result:
You have to do a lot of manual work to expose the different software to the user via a custom runscript (and be a generally decent programmer).
All software must share the same metadata, environment, and labels.
Under these conditions, containers are at best black boxes with unclear
delineation between software provided, and only one context of running
anything. The container creator shouldn’t need to spend inordinate
amounts of time writing custom runscripts to support multiple functions
and inputs. Each of foo
and bar
should be easy to define, and have its own
runscript, environment, labels, tests and help section.
Container Transparency¶
Applications that use the SCI-F make foo
and bar
transparent, and solve the problem of mixed up
modules. Our simple issue of mixed up modules could be solved if we
could do this:
Bootstrap:docker
From: ubuntu:16.04
%appenv foo
BEST_GUY=foo
export BEST_GUY
%appenv bar
BEST_GUY=bar
export BEST_GUY
%apprun foo
echo The best guy is $BEST_GUY
%apprun bar
echo The best guy is $BEST_GUY
and generate the container as follows:
$ sudo singularity build foobar.simg Singularity
and finally, run the container with the context of foo
and then bar
$ singularity run --app bar foobar.simg
The best guy is bar
$ singularity run --app foo foobar.simg
The best guy is foo
Using SCI-F apps, a user can easily discover both foo
and bar
without knowing
anything about the container:
singularity apps foobar.simg
bar
foo
Each application can be inspected individually:
singularity inspect --app foo foobar.simg
{
"SCIF_APP_NAME": "foo",
"SCIF_APP_SIZE": "1MB"
}
Container Modularity¶
This behavior is made possible by a simple, clean organization that
is tied to a set of sections in the build recipe relevant to each app.
For example, I can specify custom install procedures (and they are
relevant to each app’s specific base defined under /scif/apps
), labels, tests, and
help sections. Before we examine the sections, consider what the organization looks like, for each app:
/scif/apps/
foo/
bin/
lib/
scif/
runscript.help
runscript
env/
01-base.sh
90-environment.sh
bar/
....
If you are familiar with Singularity, the above should be very similar to other environments.
It mirrors the Singularity (main container) metadata folder, except
instead of .singularity.d
we have scif
. The name and base scif
is chosen intentionally to be
something short, and likely to be unique. On the level of organization
and metadata, these internal apps are like little containers. You need to remember all the path details because you can use environment variables in your runscripts,
etc. Here we are looking at the environment active for lolcat:
singularity exec --app foo foobar.simg env | grep foo
Consider the output of the above in sections, you will notice
some interesting things. First, notice that the app’s bin
has been added to
the path, and its lib
folder added to the LD_LIBRARY_PATH
. This means that anything you drop in
either will automatically be added. You don’t need to make these folders
either, they are created for you.
LD_LIBRARY_PATH=/scif/apps/foo/lib::/.singularity.d/libs
PATH=/scif/apps/foo/bin:/scif/apps/foo:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Next, notice the environment variables relevant to the active app’s (foo) data and metadata. They look like the following:
SCIF_APPOUTPUT=/scif/data/foo/output
SCIF_APPDATA=/scif/data/foo
SCIF_APPINPUT=/scif/data/foo/input
SCIF_APPMETA=/scif/apps/foo/scif
SCIF_APPROOT=/scif/apps/foo
SCIF_APPNAME=foo
We also have foo’s environment variables defined under %appenv foo
, and
importantly, we don’t see bar’s.
BEST_GUY=foo
Also provided are more global paths for data and apps:
SCIF_APPS=/scif/apps
SCIF_DATA=/scif/data
Note, each application has its own modular location. When you do an %appinstall foo
,
the commands are all done in context of that base. The bin
and lib
directories are
also automatically generated. Consider a simple application.
Just add a script and name it:
%appfiles foo
runfoo.sh bin/runfoo.sh
and then maybe for install I’d make it executable
%appinstall foo
chmod u+x bin/runfoo.sh
You don’t even need files! You could just do this.
%appinstall foo
echo 'echo "Hello Foo."' >> bin/runfoo.sh
chmod u+x bin/runfoo.sh
We can summarize these observations about using apps:
the specific environment (
%appenv_foo
) is active becauseBEST_APP
is foothe lib folder in foo’s base is added to the LD_LIBRARY_PATH
the bin folder is added to the path
locations for input, output, and general data are exposed. It’s up to you how you use these, but you can predictably know that a well made application will look for inputs and outputs in it’s specific folder.
environment variables are provided for the app’s root, it’s data, and it’s name
Sections¶
Finding the section %appinstall
, %apphelp
, or %apprun
is indication of an application command.
The following string is parsed as the name of the application, and
this folder is created, in lowercase, under /scif/apps
if it doesn’t exist. A
singularity metadata folder, .singularity.d, equivalent to the
container’s main folder, is generated inside the application. An
application thus is like a smaller image inside of it’s parent.
Specifically, SCI-F defines the following new sections for the build
recipe, where each is optional for zero or more apps:
%appinstall corresponds to executing commands within the folder to install the application. These commands would previously belong in %post, but are now attributable to the application.
%apphelp is written as a file called runscript.help in the application’s metadata folder, where the Singularity software knows where to find it. If no help section is provided, the software simply will alert the user and show the files provided for inspection.
%apprun is also written as a file called runscript.exec in the application’s metadata folder, and again looked for when the user asks to run the software. If not found, the container should default to shelling into that location.
%applabels will write a labels.json in the application’s metadata folder, allowing for application specific labels.
%appenv will write an environment file in the application’s base folder, allowing for definition of application specific environment variables.
%apptest will run tests specific to the application, with present working directory assumed to be the software module’s folder
%appfiles will add files to the app’s base at /scif/apps/<app>
Interaction¶
The complete output of a grep
to the environment when
running foo
in the first example was not shown because the remainder of variables
are more germane to a discussion about application interaction. Essentially, when
any application is active, we also have named variable that can explicitly
reference the environment file, labels file, runscript, lib
and bin
folders for
all app’s in the container. For our above Singularity Recipe, we would
also find:
SCIF_APPDATA_bar=/scif/data/bar
SCIF_APPRUN_bar=/scif/apps/bar/scif/runscript
SCIF_APPROOT_bar=/scif/apps/bar
SCIF_APPLIB_bar=/scif/apps/bar/lib
SCIF_APPMETA_bar=/scif/apps/bar/scif
SCIF_APPBIN_bar=/scif/apps/bar/bin
SCIF_APPENV_bar=/scif/apps/bar/scif/env/90-environment.sh
SCIF_APPLABELS_bar=/scif/apps/bar/scif/labels.json
SCIF_APPENV_foo=/scif/apps/foo/scif/env/90-environment.sh
SCIF_APPLABELS_foo=/scif/apps/foo/scif/labels.json
SCIF_APPDATA_foo=/scif/data/foo
SCIF_APPRUN_foo=/scif/apps/foo/scif/runscript
SCIF_APPROOT_foo=/scif/apps/foo
SCIF_APPLIB_foo=/scif/apps/foo/lib
SCIF_APPMETA_foo=/scif/apps/foo/scif
SCIF_APPBIN_foo=/scif/apps/foo/bin
This design means that we can have apps interact with one another internally. For example, let’s modify the recipe a bit:
Bootstrap:docker
From: ubuntu:16.04
%appenv cow
ANIMAL=COW
NOISE=moo
export ANIMAL NOISE
%appenv bird
NOISE=tweet
ANIMAL=BIRD
export ANIMAL
%apprun moo
echo The ${ANIMAL} goes ${NOISE}
%appenv moo
. ${APPENV_cow}
In the above example, we have three apps. One for a cow, one for a bird,
and a third that depends on the cow. We can’t define global functions or
environment variables (in %post
or /environment
, respectively) because they would
interfere with the third app, bird, that has equivalently named
variables. What we do then, is source the environment for “cow” in the
environment for “moo” and the result is what we would want:
$ singularity run --app moo /tmp/one.simg
The COW goes moo
The same is true for each of the labels, environment, runscript, bin, and lib. The following variables are available to you, for each application in the container, whenever any application is run:
**SCIF_APPBIN_*: the path to the bin folder, if you want to add an application that isn’t active to your
PATH
**SCIF_APPLIB_*: the path to the lib folder, if you want to add an application that isn’t active to your ‘LD_LIBRARY_PATH‘
**SCIF_APPRUN_*: the app’s runscript (so you can call it from elsewhere)
**SCIF_APPMETA_*: the path to the metadata folder for the app
**SCIF_APPENV_*: the path to the primary environment file (for sourcing) if it exists
**SCIF_APPROOT_*: the application’s install folder
**SCIF_APPDATA_*: the application’s data folder
**SCIF_APPLABELS_*: The path to the label.json in the metadata folder, if it exists
Singularity containers are already reproducible in that they package dependencies. The basic format of SCI-F adds to that by making the software inside of containers modular, predictable, and programmatically accessible. By pre-setting some set of steps, labels, or variables in the runscript is associated with a particular action of the container, users can better encapsulate how dependencies relate to each step in a scientific work-flow. Making containers can be challenging. When a scientist starts to write a recipe for his set of tools, she probably doesn’t know where to put various tags and data. The SCI-F file system makes it easy to build consistent maintainable containers.
SCI-F Example: Cowsay Container¶
As an example, we will use the `cowsay container`_. cowsay
is a program that generates ASCII pictures of a cow with a message.
It also uses the fortune
program to produce random “fortunes” and the lolcat
application that adds rainbow color to an ASCII string.
Warning
Important! This example has been developed for Singularity 2.4.
Download the recipe, and save it to your present working directory.
wget https://raw.githubusercontent.com/sylabs/singularity/master/examples/apps/Singularity.cowsay
sudo singularity build moo.simg Singularity.cowsay
Determine what apps are installed using the following command:
singularity apps moo.simg
cowsay
fortune
lolcat
Ask for help for a specific application as follows:
singularity help --app fortune moo.simg
fortune is the best app
A simple loop can be used to ask for help from all apps (without knowing in advance what they are):
for app in $(singularity apps moo.simg)
do
singularity help --app $app moo.simg
done
cowsay is the best app
fortune is the best app
lolcat is the best app
To run the fortune
application enter the following (the actual fortune is random, so your display may differ):
singularity run --app fortune moo.simg
My dear People.
My dear Bagginses and Boffins, and my dear Tooks and Brandybucks,
and Grubbs, and Chubbs, and Burrowses, and Hornblowers, and Bolgers,
Bracegirdles, Goodbodies, Brockhouses and Proudfoots. Also my good
Sackville Bagginses that I welcome back at last to Bag End. Today is my
one hundred and eleventh birthday: I am eleventy-one today!"
-- J. R. R. Tolkien
Next, pipe the output of fortune
into lolcat
to add color to the fortune.
singularity run --app fortune moo.simg | singularity run --app lolcat moo.simg
You will be surrounded by luxury.
Send the output of fortune
to the cowsay
application.
singularity run --app fortune moo.simg | singularity run --app cowsay moo.simg
________________________________________
/ Executive ability is prominent in your \
\ make-up. /
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Finally use all three applications and demonstrate how to use an environment variable for the command:
CMD="singularity run --app"
$CMD fortune moo.simg | $CMD cowsay moo.simg | $CMD lolcat moo.simg
_________________________________________
/ Ships are safe in harbor, but they were \
\ never meant to stay there. /
-----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
The application can be inspected with the following command:
singularity inspect --app fortune moo.simg
{
"SCIF_APP_NAME": "fortune",
"SCIF_APP_SIZE": "1MB"
}
If you want to see the full specification or create your own Scientific Filesystem integration (doesn’t have to be Singularity, or Docker, or containers!) see the full documentation.
Also, you can follow along with this example by going to: take a look at these examples


Pickle Praise
Fermented Foods like pickles, saurkraut, and kimchi possess numerous benefits.
- Natural Source of Probiotics
- Create Protective intestinal lining
- Produce gut healthy vitamins and enzymes
- Enhance Foods Nutrient Content
- Regulate Appetite
- Help in treating Candida
- May reduce social anxiety


WITNESS LIST Jurisprudence Committee (Subcommittee on Subcommittee on SB 999) April 9, 1997-4:00P SB 999 Registering, but not testifying: On: Schraub, B.B. Judge (3rd Admin. Judicial Reg), Seguin


--- layout: post title: Where to store config, web.config or not... categories: [] tags: webdrawer serviceapi status: publish type: post published: true meta: {} ---
For those who customise WebDrawer on one machine and then push it to a production machine this may prove handy. I wanted to change the setup of IIS on my dev machine to not update the web.config when I change the authentication settings. Here is what I did...
Remove the <security /> section from all web.config files that have already been updated, otherwise you will get an error when you attempt to open these applications. Also check c:\inetpub\wwwroot\web.config to ensure that authentication has not been set here.
Go through each application in IIS and ensure the authentication settings are correct, this will update applicationHost.config.
Setting these settings to Read Only prevents them being updated in the application specific web.config, instead they will be set in the applicationHost.config


--- layout: newsstory title: WOO-HOO! match: Yeltz 4 Rothwell 0 ---
This was a CRUCIAL win in our relegation battle. A loss would have dropped us into the relegation zone, but two goals from young Birch and another two from Pie-arce has moved us up a couple of places in the table to a whopping 16th.
If you haven't already heard, Delton Francis has been sold to Conference side Kingstonian for a fee of either £10,000 or £18,000 depending on who you listen to. The longstanding rumours of Evran's problems with the law have been proved true - he's in court on March 8th on drugs-related charges - so I've no idea who's going to playing up front soon.
On a "brighter" note, the Halesowen News says Hastings will be resigning from the Premier League next season as their Mr Moneybags has pulled out, which should mean one less team will be relegated . Hopefully we won't be depending on this at the end of the season


{% extends 'layout.html' %} {% from 'includes/_formhelpers.html' import render_field %} {% block body %}
Online Teaching
Tuition at my Place
Tuition at your Place


Interpreting Results
Use the ComparativeMarkerSelectionViewer to view the result file. A paragraph discussing what to look for and how to interpret
what you find. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent fermentum turpis commodo lorem luctus suscipit.
Curabitur adipiscing hendrerit orci. Praesent vitae libero. Suspendisse id turpis in magna rutrum molestie. Quisque tristique
mattis purus. Etiam ullamcorper dapibus orci. Vestibulum urna purus, scelerisque in, porta in, molestie semper, odio. Sed
sodales ante vel risus. Aenean porttitor pharetra dui. Donec iaculis, velit vel commodo scelerisque, eros est pellentesque
nulla, nec aliquet sem nunc non lorem. Sed vitae nisi sit amet metus consectetuer pretium. Donec bibendum urna. Donec commodo,
tellus vel egestas condimentum, enim augue elementum mi, at dictum lacus mi eget tortor. Cras dolor.
If appropriate, discuss next steps. Sed sodales ante vel risus. Aenean porttitor pharetra dui. Donec iaculis, velit vel commodo
scelerisque, eros est pellentesque nulla, nec aliquet sem nunc non lorem. Sed vitae nisi sit amet metus consectetuer pretium.
Donec bibendum urna. Donec commodo, tellus vel egestas condimentum, enim augue elementum mi, at dictum lacus mi eget tortor.
Cras dolor.
Basic Parameters
Parameters that are essential to the analysis.
input filename :
Required
Gene expression data file. Preprocess the data. Procedures such as FDR and FWER control for multiple hypotheses testing by
"inflating" the nominal p-values of the single hypotheses (genes). This allows for controlling the number of false positives
but at the cost of potentially increasing the number of false negatives (actual markers that are wrongly declared not differentially
expressed). Preprocessing the data reduces the number of hypotheses (genes) to be tested.
cls filename :
Required
Class file
Advanced Parameters
Parameters whose default values are sufficient for most analyses.
confound variable cls filename :
Optional
If you specify this class file, permutations shuffle the labels in
Class file only within the subsets defined by this
class file. For example, when identifying genes
that are differentially expressed between the classes Tumor and Normal, tissue type
might be a confounding variable. This file would define classes for each tissue type.
During permutations, the module shuffles the Tumor/Normal labels only among samples that have the same tissue type.
test direction :
Required
The test to perform.
By default, ComparativeMarkerSelection performs a two-sided test, which tests for differential expression between classes.
If you are interested in a one-sided test (up-regulated in class 0 or in class 1), perform the one-sided test, perform the
two-sided test, and consider both sets of results.
Options
- Class 0
: up-regulated for class 0
- Class 1
: up-regulated for class 1
- Two-sided
: differentially expressed between class 0 and class 1
test statistic :
Required
The statistic to use.
Options
- t-test
:
The difference between the mean expression of class 1 and class 2. The
difference is divided by the sum of the standard deviation of class 1 and 2 to penalize genes with wide variation. In the
equation:
- μ is the average
- σ is the standard deviation
- n is the number of samples
- t-test (median)
:
Same as t-test, but uses median rather than average.
- t-test (min std)
:
Same as t-test, but enforces a minimum value for σ (minimal standard deviation).
- t-test (median, min std)
:
Same as t-test, but uses median rather than average and enforces a minimum value for σ (minimal standard deviation).
- SNR (signal-to-noise ratio)
:
In the equation:
- μ is the average
- σ is the standard deviation
- snr (median)
:
Same as snr, but uses median rather than average.
- snr (min std)
:
Same as snr, but enforces a minimum value for σ (minimal standard deviation).
- snr (median, min std)
:
Same as snr, but uses median rather than average and enforces a minimum value for σ (minimal standard deviation).
min std :
Optional
Used only if test statistic includes the min std option. If σ is less than min std, σ is set to min std.
number of permutations :
Required
The number of permutations to perform (use 0 to calculate asymptotic p-values). The number of permutations you specify depends
on the number of hypotheses being tested and the significance level that you want to achieve (3). The greater the number of
permutations, the more accurate the p value.
Generally, if the data set includes at least 10 samples per class, use the default value of 1000 permutations
to ensure accurate
p-values. If the data set includes fewer than 10 samples in any class, permuting the
samples cannot give an accurate
p-value; specify 0 permutations to use asymptotic
p-values
instead.
complete :
Required
Whether to perform all possible permutations. By default, complete is set to no and number of permutations determines the
number of permutations performed. If you have a small number of samples, you might want to perform all possible permutations.
balanced :
Required
Whether to perform balanced permutations. By default, balanced is set to no and phenotype labels are permuted without regard
to the number of samples per phenotype (for example, if your dataset has 12 samples in class 0 and 10 in class 1, any permutation
of class 0 has 12 randomly selected samples).
If you set balanced to yes, phenotype labels are permuted by balancing the number of samples per phenotype (for example,
if your dataset has 12 samples in class 0 and 10 in class 1, any permutation of class 0 has an equal number of samples from
class 0 and class 1. Balancing samples is rarely necessary, but may be useful if your samples are very unevenly distributed
across phenotypes.
random seed :
Required
The seed for the random number generator.
smooth p values :
Required
Whether to smooth p-values by using the Laplace’s Rule of Succession. By default, smooth p values is set to yes, which means
p-values are always less than 1.0 and greater than 0.0.
phenotype test :
Required
If the data set includes more than two classes, use this parameter
to analyze each class against all others (one-versus-all) or all class pairs
(all pairs).
Note: The p-values obtained from the one-versus-all comparison are not fully corrected for multiple hypothesis testing.
output file :
Required
The name of the output file.
References
Benjamini,
Y. and Hochberg, Y. (1995) Controlling the False Discovery Rate: A
Practical and Powerful Approach to Multiple Testing. Journal of the
Royal Statistical Society. Series B (Methodological). 57(1): p.
289-300.
Golub,
T., Slonim, D. et al. (1999) Molecular Classification of Cancer: Class
Discovery and Class Prediction by Gene Expression. Science 286,
531-537.
Good, P.
(2000) Permutation Tests: A Practical Guide for Testing Hypotheses, 2nd
Ed., New York: Springer-Verlag
Gould J.,
Getz G., Monti S., Reich M., and Mesirov J.P. (2006) Comparative gene marker
selection suite. Bioinformatics 22,
1924-1925; doi:10.1093/bioinformatics/btl196.
Lu, J.,
Getz, G., Miska, E., et al. (2005) MicroRNA Expression Profiles Classify
Human Cancers. Nature 435, 834-838
Storey,
J.D. and R. Tibshirani (2003) Statistical significance for genomewide
studies. PNAS, 100(16): p. 9440-9445.
Westfall,
P.H. and S. S. Young (1993) Resampling-Based Multiple Testing: Examples
and Methods for p-Value Adjustment. Wiley Series in Probability and
Statistics. New York: Wiley.


{% extends "base.html" %} {% block content %}
You can adjust the mood parameters below and click "New Recommendations" to customize your listening experience. The chart at the bottom of the page displays all the mood features for each recommended song. You can learn more about the song features along with the API that powers this application here.


PerfCake
News
Community
Get started!
Documentation
Get Support
PerfCake
Performance Test Results Report
Table of Contents
Echo in Ruby
Echo in JavaScript
Echo in Python
Echo in Java
Group: perf, Match of axis: Minimum
Group: perf, Match of axis: Maximum
Group: perf, Match of axis: Average
Group: perf, Match of axis: Result
Charts for group: perf
Plain results
Echo in Ruby
Echo in JavaScript
Echo in Python
Echo in Java
Combined results
Group: perf, Match of axis: Minimum
Group: perf, Match of axis: Maximum
Group: perf, Match of axis: Average
Group: perf, Match of axis: Result


Methods
Public Class methods
[ show source ]
# File vendor/rails/actionpack/lib/action_controller/uploaded_file.rb, line 10 10: def self.extended(object) 11: object.class_eval do 12: attr_accessor :original_path, :content_type 13: alias_method :local_path, :path 14: end 15: end
[ show source ]
# File vendor/rails/actionpack/lib/action_controller/uploaded_file.rb, line 3 3: def self.included(base) 4: base.class_eval do 5: attr_accessor :original_path, :content_type 6: alias_method :local_path, :path 7: end 8: end
Public Instance methods
Take the basename of the upload‘s original filename. This handles the full Windows paths given by Internet Explorer (and perhaps other broken user agents) without affecting those which give the lone filename. The Windows regexp is adapted from Perl‘s File::Basename.
[ show source ]
# File vendor/rails/actionpack/lib/action_controller/uploaded_file.rb, line 22 22: def original_filename 23: unless defined? @original_filename 24: @original_filename = 25: unless original_path.blank? 26: if original_path =~ /^(?:.*[:\\\/])?(.*)/m 27: $1 28: else 29: File.basename original_path 30: end 31: end 32: end 33: @original_filename 34: end


Generating a Schema for a Simple Type
This example shows how to extend schema generation to cover a specific type that isn't defined by the type's properties. This is useful for many of the scalar-like value types, such as bool
, int
, DateTime
, or TimeSpan
.
A generator is the appropriate tool for this job.
For this example, we will be implementing a custom generator that handles the TimeSpan
type by creating a schema that expects a duration
-formatted string.
// Generators must implement ISchemaGenerator
class TimeSpanSchemaGenerator : ISchemaGenerator
{
public bool Handles(Type type)
{
return type == typeof(TimeSpan);
}
public void AddConstraints(SchemaGeneratorContext context)
{
context.Intents.Add(new TypeIntent(SchemaValueType.String));
context.Intents.Add(new FormatIntent(Formats.Duration));
}
}
Once the generator is complete, we must register an instance:
GeneratorRegistry.Register(new TimeSpanSchemaGenerator());
All done. Generation can now handle TimeSpan
s.


{% extends "caffeine_oauth2/mail_body_base.html" %}{% load i18n %} {% block title %}[{{ site.name }}] {% blocktrans with appname=application.name %}Your API client {{ appname }} has been rejected{% endblocktrans %} {% endblock %} {% block content_start %}{% blocktrans with user=application.user %}Hello {{ user }},{% endblocktrans %}{% endblock %} {% block content %} {% blocktrans with appname=application.name sitename=site.name %}
we are sorry to tell you that your API client registration {{ appname }} for {{ sitename }} has been rejected because of the following reason(s):
{{ reasoning }}
You can try to register your API client again once you could resolve the mentioned problems.
{% endblocktrans %} {% endblock %}


Google Assistant now works better with G Suite accounts
by Corbin DavenportOne of the most common complaints we hear whenever a new Google product arrives (besides the pile of "when is it getting shut down" unoriginal jokes) is that G Suite users either can't try the new product at all, or there is limited functionality. Assistant has historically been extremely limited for G Suite accounts, but some of that is changing today.
"We’re opening a beta program to allow G Suite users to accomplish more on-the-go with the Google Assistant when logged in with a G Suite account," Google wrote on its G Suite blog. The new functionality includes creating/rescheduling calendar events, sending an email, and dialing into a meeting.
The beta program has to be enabled by the admin(s) of each G Suite organization, so it's not something individuals can turn on right now. There's also one caveat: if you have both a regular Google account and a G Suite account, Assistant can only answer questions for one of them at a time.
There's no word on when G Suite accounts will be able to use the updated Google Assistant that first arrived on the Pixel 4. The post also didn't mention when reminders will become available.
Source:
G Suite Updates