Help
The Carnatic Music Transliterator allows you to create text for carnatic music
compositions in a "unified" transliteration scheme so that it can be
effectively rendered in all the carnatic music languages (sanskrit, telugu, tamizh, kannada
and malayalam). See
Unified Transliteration Scheme for Carnatic
Music Compositions for more information on the scheme.
General Usage
You can either start typing from scratch, or you can paste HTML or word content. Use the various
formatting buttons on top to create text in
bold,
italic,
underline, and also
to create bullet list, numbered lists, headings etc. As mentioned above, the text is expected to be
in the
unified transliteration scheme for carnatic music
Once you have created the text, you use the
button to
translate to the various languages. Use the tabs on top to switch between different languages
Paragraphs (RETURN) and newlines (Shift+RETURN)
When entering text, if you press the RETURN key, the editor will create a new
paragraph. If you instead want to new just a new line without the additional space
taken by paragraph, press Shift key while pressing the RETURN key.
Printable View, Printinng
Once you have translated the transliteration text to the target languages, you can switch to a printable view
using the
Printable View link the bottom. This view includes only the contents for the
selected language(s), which you can then print to your printer using the print options of the browser.
Getting back to the editor - the Back link
The printable view, includes a
Back link to take you back to the editor. You should use
this link and
not the Back button of your browser. Note that as desired, the
Back link
will not be included in your hard copy print.
Including more than one language in printable view
By default, the printable view will include the translation for the currently selected target language. So,
if you are currently viewing Telugu, and you click on the
Printable View link, the printable
view will include only the Telugu rendition. You can include multiple languages, and also control the
order in which the languages appear by changing the print options.
To view the print options,
click on the + button next to the Printable View link. This will show two lists
side by side with two buttons >> and <<
in-between. The left side list contains all the languages including a special entry <Current> to
indicate the currently selected language. The right side list contains the languages that will be included
in the printable view in the order they appear in the list. Use the >>
button to add a language to the printable view. Use the <<
button to remove a language from the printable view.
Variables - what are they and how to use them
Some common terms which appear in carnatic music books
outside of the
actual lyrics (i.e. sAhitya) have various spelling and pronounciations in the different languages.
For example, "Raga" (as in raga of the krithi), is rAga in kannada but rAgam in
tamizh. So if you enter it as rAga in the input, then the translation would be inappropriate for tamizh as
it would appear as
ராக in tamizh. On the other hand, if you specify it
as rAgam, then it would appear as
ರಾಗಂ, which is less than ideal than
ರಾಗ. There are many many examples of such terms in this category:
- The term for language as in of a krithi (bAsha in sanskrit, kannada, but bashai or
the better mozhi in tamizh),
- Names of composers such as tyAgarAja (which would be spelt as tiyAgarAjar in tamizh)
Some raga names like AbhOgi (abhOgi in kannada, telugu), kAmbhOji (kAmbOdi in tamizh)
Currently, the list of variables are pre-defined, and only a handful are supported at this
point
To solve this problem, the editor has the concept of a variable, which is a term in
the input that translates to different words according to the language. There are several ways of
introducing variables into the content that needs to be transliterated.
How to insert a variable
To insert a variable at the current location, you click on the
button. This will bring up a window from which you can select the variable you want to insert. The inserted
variable will be shown in blue text with a gray background (e.g.
rAga).
How to convert normal text to a variable
If you have already entered in a text, you can tell the editor to convert it into a variable by
clicking on
button. The editor
will grab the current word, and search the list of pre-defined variables for a match. It will
compare the current word against the english transliteration for
all of the languages
for a match. If a match is found, it will transform the current word into a variable (which
will turn it into bluex text against a gray background).
Note that the text in the english translation, would be the text you entered. This points at
an advantage of using the
button vs. the button
in that you have more control over how the text appears in the english "translation". For
example, for the the variable for raga, if you use the
button, the english text will always be rAga. However, with this approach, your input text could be any one of
rAga, raga, Raga, rAgam, rAgamu etc., and all these will convert to the same variable, and the english
"translation" will retain the original text.
Find and replace suitable words to variables
: If you are pasting text from an existing
source, then it may be convenient to click on the
button. This will
search the text for words that are suitable for translation to variables. This can save the trouble of
figuring out which words in your text should be variables. Words that are suitable are ones that appear in bold
amongst themselves, as in the context of headings, and also words in a certain form (e.g. Raga: i.e. a word that
matches a variable value and is followed by a colon).
Of course, using the
may not always work flawlessly, in which case you can use the other approaches to insert new variables,
and convert individual words to variables.
Remove hyperlinks
If you are pasting text from an existing HTML source (as in a web-page), you may
want to remove the anchors which are usually shown underlined in a browser, which you may not want in
your transliterated content. You can do this by clicking on the
button.
Clear Contents
Use
button to
clear the contents of the editor.


Arrest after building sites burgled
by New Zealand PoliceA 43-year-old Christchurch man was arrested and charged with the burglary of two building sites, in the new subdivision near Townsend Road Rangiora.
At about 10:30pm Wednesday 20 November the man went to the building sites where he loaded his van with landscaping equipment from one site, before removing a trailer from the neighbouring site.
Once the burglaries were discovered, Police were led to the alleged offenders address by a GPS tracking device that was on the stolen property.
The vehicle involved was also identified through surveillance cameras set up by one of the builders.
Through the security measures set in place by these builders, Police were able to make an arrest and return the stolen property.
The alleged offender is due to appear in Christchurch District Court on Monday 25 November.
Canterbury Police want to remind the community to take precautions against burglars.
The following measures will help reduce crime:
• preventing easy access or opportunity
• engraving tools
• locking and securing premises
• using available technology to alarm and monitor your property
• having tracking devices on valuable items
ENDS


Biology 155 is a 3-credit lecture course designed to give both science and non-science majors a basic understanding of the aging process, with special emphasis on aging as it relates to the human body and health. The first third of the course will discuss important aging terminology, methods of measuring aging, current theories of the aging process, and research models used to study aging. The later two thirds of the course will review aging as related to specific body systems. As such, portions of lessons will review normal anatomy (structure naming) and physiology (body function) of these body systems. In this later section, details of both senescence and age-related disease processes will be discussed.
Upon completion of this course, you will have:
| Lesson | Topic |
|---|---|
| 1 | Getting Started |
| 2 | Overview of Aging and Life Expectancy |
| 3 | Theories of Aging |
| 4 | Aging and Population Demography |
| 5 | Cancer, Aging, and the Immune System |
| 6 | Cutaneous Aging |
| 7 | Aging of the Musculoskeletal System |
| 8 | Mid-Course Exam |
| 9 | The Nervous System and Aging; Special Senses and Aging |
| 10 | Special Senses and Aging |
| 11 | Aging and the Cardiovascular System |
| 12 | Aging of the Respiratory and Urinary Systems |
| 13 | Endocrine Changes in the Elderly |
| 14 | Reproductive System Aging |
| 15 | Final Exam |
Digovanna, Augustine. Human Aging, Biological Perspectives, 2nd edtion. McGraw Hill.
Your course grade will be based upon your performance on the lesson assignments and two examinations. The lesson assignments will be 1/3 of the final course grade, with the mid-course counting as 1/3 and the final counting as the last 1/3. Examinations will have 30 multiple choice, matching and true/false questions, worth 80% of the exam points, and the remaining 20% of the exam points will be performance on a short essay and term definitions. The mid-course exam will stress material developed in lesson assignments 2-7. The final exam will stress material developed in lesson assignments 9-14, and will not be comprehensive. That said, some broad concepts developed throughout the course, could be found in some questions.
| Activity | % of Grade |
|---|---|
| Lessons (average score) | 33.3% |
| Mid-Course Exam | 33.3% |
| Final Exam | 33.3% |
| Letter Grade | % Range |
|---|---|
| A | 93-100% |
| A- | 90-92% |
| B+ | 87-89% |
| B | 83-85% |
| B- | 80-82% |
| C+ | 77-79% |
| C | 70-76% |
| D | 60-69% |
| F | < 60% |


404
Looks like this page is missing.
Don't worry though, our best
man is on the case.
Meanwhile, why don't try again by going
BACK HOMELooks like this page is missing.
Don't worry though, our best
man is on the case.
Meanwhile, why don't try again by going
BACK HOME


Keeping this general until the machine is retired:
Make sure your webtools are performing as they need to be. Ie: following redirections or submitting requests properly
Always audit all instances of special characters being passed and allowed. Even if something doesn't immediately look vulnerable, user data may be used later in multiple places.
This also applies to data being truncated. ie if half of your data is gone, but trailing special characters remain. Did it get executed? Filtered? Improper quote terminations?
Enumeration is sometimes as simple as "what is not default". If something sticks out, run with it.
I ended up doing it the 'unintended' way through double sqli. There were hints to the 'nightmare' box on HTB and using SQLi payloads to create accounts eventually results in dumping all of the notes. After some parsing, you can see the login information left in the new-site note.
Ippsec walkthrough below:
Browse to register.php, create an account.
Enumerate users through error based enum.
Login and play around. Notice tyler@secnotes
New notes don't filter HTML tags at all. Test with ippsec
Notice the change_pass.php doesn't have a CSRF token nor does it ask for confirmation of the old password.
Attack path: force someone else to update their password unknowningly
Send a note to tyler directing him to your webserver

<iframe src="http://<IP_ADDRESS>/change_pass.php?password=PleaseSubscribe&confirm_password=PleaseSubscribe&submit=submit">

Maybe the powershell agent is not accepting iframes? Maybe another way. Try another iframe and confirm iframes and powershell don't like each other.
Just force him submitting a note with: http://<IP_ADDRESS>/change_pass.php?password=PleaseSubscribe&confirm_password=PleaseSubscribe&submit=submit
Login and see all of the notes. new site note has a username and password being used in what looks like a windows share
smbmap -u tyler -p '' -H <IP_ADDRESS>
and see new-site with READ, WRITE access
so upload a webshell. This is the IIS website on 8808.
PrivEsc:
This was a bit tricky, but notice that there is a ton of Windows Subsystem for Linux stuff. bash.lnk for example.
Another way to identify this is to check: appdata\local\packages and look for:
CanonicalGroupLimited.Ubuntu18 etc etc etc
and this is where you can browse the entire Linux filesystem in cmd/powershell
Just type:
bash
and get into a bash prompt as root.
check out the /root/.bash_history and woops! administrator password!
GG


throwaway account
`Prev `__
T
`Next `__
--------------
**throwaway account**: n.
1. An inexpensive Internet account purchased on a legitimate
`*ISP* <../I/ISP.html>`__ for the sole purpose of spewing
`*spam* <../S/spam.html>`__.
2. An inexpensive Internet account obtained for the sole purpose of
doing something which requires a valid email address but being able to
ignore spam since the user will not look at the account again.
--------------
+----------------------------------------+----------------------------+-------------------------+
| `Prev `__ | `Up <../T.html>`__ | `Next `__ |
+----------------------------------------+----------------------------+-------------------------+
| three-finger salute | `Home <../index.html>`__ | thud |
+----------------------------------------+----------------------------+-------------------------+


Changing Translatable Modules to Reference Modules
How to change a translatable module for a secondary language into a reference module that shares the same content as the default language module. This permanently deletes any translated content and displays default language version of this module to users who are viewing the site in the secondary language. Translators and Administrators only.
- Navigate to Admin > Advanced Settings > Languages - OR - Go to a Languages module.
- Select the Content Localization tab.
- At Select a Page, find or select the required page.
- Locate the required language and click the Detach button located beside the title of each module to be modified.
-
Click the Update button. The selected module is now a reference copy of the default language module and the module name cannot be edited.


This project template is created to the spec of Spojko board with the 34-pin header for power supply. You will need to configure else to suit your design.
The board outline looks like the following:
See project files for licensing details. This project is open source.(c)2017 tvlada73


Try out our Premium Member services: Virtual Legal Assistant, Query Alert Service and an ad-free experience. Free for one month and pay only if you like it.
IN THE HIGH COURT OF JUDICATURE AT PATNA Criminal Miscellaneous No.26597 of 2018 Arising Out of PS.Case No. -69 Year- 2018 Thana -BARUN District- AURANGABAD ====================================================== 1. Birendra Singh, son of Banarsi Singh, resident of village - Hundra Kala, P.S. Belaon, District Kaimur at Bhabua. 2. Indrajeet Singh, son of late Ramchandra Singh, resident of village - Belaon, P.S. - Belaon, District - Kaimur at Bhabua. .... .... Petitioner/s Versus 1. The State of Bihar. 2. M.D. of Mines & Minerals Department, Patna .... .... Opposite Party/s ====================================================== Appearance : For the Petitioner/s : Mr. Rajani Kant Pandey, Advocate For the Opposite Party/s : Mr. Akshay Lal Pandit, APP ====================================================== CORAM: HONOURABLE MR. JUSTICE SANJAY PRIYA ORAL ORDER
3/ 17-05-2018 Heard learned counsel for the petitioners and learned APP for the State.
Petitioners apprehend their arrest in Barun P.S. Case No.69 of 2018 instituted for the offence under Section(s) 379, 420/34 Indian Penal Code, Section 4/40 of the Bihar Mines Act and Section 15 of the Prevention of Pollution Act.
It has been submitted that petitioner no.1 is Driver of Tractor and petitioner no.2 is owner of the seized Tractor, which is mentioned at serial no.23 of the seizure list.
In the written report, it is alleged that the informant raided Kochar Balu Ghat under Barun P.S. and found 35 Tractors loaded with sand. Having seen the police, the drivers after unloading the sand started fleeing away. The police chased them. Then 29 Tractor drivers having parked empty tractors succeeded Patna High Court Cr.M isc. No.26597 of 2018 (3) dt.17-05-2018 2/2 in fleeing away.
In the written report itself, it is mentioned that Tractors were lying empty. Petitioners were not present at the spot.
In the facts and circumstances of the case, prayer of the petitioners for grant of anticipatory bail is allowed. In the event of surrender/arrest of the petitioners, named above, within six weeks from today in connection with Barun P.S. Case No.69 of 2018, they shall be released on anticipatory bail on furnishing bail bond of Rs.10,000/- (ten thousand) each with two sureties of the like amount each to the satisfaction of the Chief Judicial Magistrate, Aurangaad, subject to the conditions as laid down under Section 438(2) Cr. P. C. with further conditions: (1) bailors should be local having sufficient immovable property within the jurisdiction of the court concerned, (2) petitioners shall cooperate in the trial and shall be present on each and every date fixed by the court and their absence on two consecutive dates without proper and reasonable reason will be liable to cancel their bail bonds and (3) if petitioners tamper with the evidence or the witnesses of the case, in that case, prosecution will be at liberty to move for cancellation of bail of the petitioners.
(Sanjay Priya, J) JA/-
U T


#include <PxSolverDefs.h>
Public Attributes | |
| Sc::ShapeInteraction * | shapeInteraction |
| Pointer to share interaction. Used for force threshold reports in solver. Set to NULL if using immediate mode. More... | |
| Gu::ContactPoint * | contacts |
| The start of the contacts for this pair. More... | |
| PxU32 | numContacts |
| The total number of contacs this pair references. More... | |
| bool | hasMaxImpulse |
| Defines whether this pairs has maxImpulses clamping enabled. More... | |
| bool | disableStrongFriction |
| Defines whether this pair disables strong friction (sticky friction correlation) More... | |
| bool | hasForceThresholds |
| Defines whether this pair requires force thresholds. More... | |
| PxReal | restDistance |
| A distance at which the solver should aim to hold the bodies separated. Default is 0. More... | |
| PxReal | maxCCDSeparation |
| A distance used to configure speculative CCD behavior. Default is PX_MAX_F32. Set internally in PhysX for bodies with eENABLE_SPECULATIVE_CCD on. Do not set directly! More... | |
| PxU8 * | frictionPtr |
| InOut: Friction patch correlation data. Set each frame by solver. Can be retained for improved behaviour or discarded each frame. More... | |
| PxU8 | frictionCount |
| The total number of friction patches in this pair. More... | |
| PxReal * | contactForces |
| Out: A buffer for the solver to write applied contact forces to. More... | |
| PxU32 | startFrictionPatchIndex |
| Start index of friction patch in the correlation buffer. Set by friction correlation. More... | |
| PxU32 | numFrictionPatches |
| Total number of friction patches in this pair. Set by friction correlation. More... | |
| PxU32 | startContactPatchIndex |
| The start index of this pair's contact patches in the correlation buffer. For internal use only. More... | |
| PxU16 | numContactPatches |
| Total number of contact patches. More... | |
| PxU16 | axisConstraintCount |
| Axis constraint count. Defines how many constraint rows this pair has produced. Useful for statistical purposes. More... | |
| PxReal | maxImpulse |
| PxReal | torsionalPatchRadius |
| PxReal | minTorsionalPatchRadius |
| Public Attributes inherited from PxTGSSolverConstraintPrepDescBase | |
| PxConstraintInvMassScale | invMassScales |
| In: The local mass scaling for this pair. More... | |
| PxSolverConstraintDesc * | desc |
| Output: The PxSolverConstraintDesc filled in by contact prep. More... | |
| const PxTGSSolverBodyVel * | body0 |
| In: The first body. Stores velocity information. Unused unless contact involves articulations. More... | |
| const PxTGSSolverBodyVel * | body1 |
| In: The second body. Stores velocity information. Unused unless contact involves articulations. More... | |
| const PxTGSSolverBodyTxInertia * | body0TxI |
| const PxTGSSolverBodyTxInertia * | body1TxI |
| const PxTGSSolverBodyData * | bodyData0 |
| const PxTGSSolverBodyData * | bodyData1 |
| PxTransform | bodyFrame0 |
| In: The world-space transform of the first body. More... | |
| PxTransform | bodyFrame1 |
| In: The world-space transform of the second body. More... | |
| PxSolverContactDesc::BodyState | bodyState0 |
| In: Defines what kind of actor the first body is. More... | |
| PxSolverContactDesc::BodyState | bodyState1 |
| In: Defines what kind of actor the second body is. More... | |
| PxU16 PxTGSSolverContactDesc::axisConstraintCount |
Axis constraint count. Defines how many constraint rows this pair has produced. Useful for statistical purposes.
| PxReal* PxTGSSolverContactDesc::contactForces |
Out: A buffer for the solver to write applied contact forces to.
| Gu::ContactPoint* PxTGSSolverContactDesc::contacts |
The start of the contacts for this pair.
| bool PxTGSSolverContactDesc::disableStrongFriction |
Defines whether this pair disables strong friction (sticky friction correlation)
| PxU8 PxTGSSolverContactDesc::frictionCount |
The total number of friction patches in this pair.
| PxU8* PxTGSSolverContactDesc::frictionPtr |
InOut: Friction patch correlation data. Set each frame by solver. Can be retained for improved behaviour or discarded each frame.
| bool PxTGSSolverContactDesc::hasForceThresholds |
Defines whether this pair requires force thresholds.
| bool PxTGSSolverContactDesc::hasMaxImpulse |
Defines whether this pairs has maxImpulses clamping enabled.
| PxReal PxTGSSolverContactDesc::maxCCDSeparation |
A distance used to configure speculative CCD behavior. Default is PX_MAX_F32. Set internally in PhysX for bodies with eENABLE_SPECULATIVE_CCD on. Do not set directly!
| PxReal PxTGSSolverContactDesc::maxImpulse |
| PxReal PxTGSSolverContactDesc::minTorsionalPatchRadius |
| PxU16 PxTGSSolverContactDesc::numContactPatches |
Total number of contact patches.
| PxU32 PxTGSSolverContactDesc::numContacts |
The total number of contacs this pair references.
| PxU32 PxTGSSolverContactDesc::numFrictionPatches |
Total number of friction patches in this pair. Set by friction correlation.
| PxReal PxTGSSolverContactDesc::restDistance |
A distance at which the solver should aim to hold the bodies separated. Default is 0.
| Sc::ShapeInteraction* PxTGSSolverContactDesc::shapeInteraction |
Pointer to share interaction. Used for force threshold reports in solver. Set to NULL if using immediate mode.
| PxU32 PxTGSSolverContactDesc::startContactPatchIndex |
The start index of this pair's contact patches in the correlation buffer. For internal use only.
| PxU32 PxTGSSolverContactDesc::startFrictionPatchIndex |
Start index of friction patch in the correlation buffer. Set by friction correlation.
| PxReal PxTGSSolverContactDesc::torsionalPatchRadius |


First page Back Continue Last page Overview Image
WASM – What it is
- WebAssembly encodes a low-level, assembly-like programming language[, that] takes the form of a module that contains definitions for functions, tables, and linear memories, as well as mutable or immutable global variables.
- A WebAssembly implementation will typically be embedded into a host environment. This environment defines how loading of modules is initiated, how imports are provided (including host-side definitions), and how exports can be accessed.
- The design goals of WebAssembly are the following: fast, safe, and portable.
- Fast: executes with near native code performance
- Safe: code is validated and executes in a memory-safe, sandboxed environment
- Platform-independent: can be embedded in browsers, run as a stand-alone VM, or integrated in other environments.
- https://webassembly.github.io/spec/core/intro/overview.html
1.


Lipstics
Price:Rs229
Lipstics
Price:Rs134
Lipstics
price:Rs179
Lipstics
Price:Rs290
Lipstics
Price:Rs290
Lipstics
priceRs379
Lipstics
Price:Rs269
Lipstics
Price:Rs175
Lipstics
price:Rs379
Lipstics
Price:Rs196
Lipstics
Price:Rs275
Lipstics
price:Rs179


Mushrooms - P. cubensis
I was at a Reggae concert when a stranger approached me. It was 8 o'clock on the second night of the three day concert, and he looked to be in his mid-40's. He offered me an eigth of cubensis for 20 dollars. I declined that offer, and proposed to him that we trade substances, for I had more of this fantastic strain of pot than I needed at the time, and I was hoping to achieve a better mushroom experience than the last panic-stricken hellish time I had spent in the fetal position in the back seat of a friend's car.  As we all know, mushrooms vary greatly by variety as it relates to the experience, and this time, at this Reggae concert, I was hoping to settle the score with my foe, psilocybe cubensis.
The man was thrilled, and we made the trade, wished each other well, and continued on our respective ways. The rest of the night was fairly uneventful, and after drifting off to sleep, safe in my tent, I awoke to a beautiful cloudless day. I wandered over to the area where my closest friends also attending the concert were, but was turned away by the people watching the gate. My friends were part of the food service crew, and therefore had different wristbands, wich gave them the priviledge of better camp sites, etc.
Then another friend came along, I told her my plight, and she bravely led me through the gate and past the 'guard' to the cool and shady other campground. I came upon the circle of tents I knew to belong to the group I was seeking. There was a tarp partly supported by a bamboo fence which created a sort of living-room area between the circle of tents. The man I had been looking for sat there on the ground talking to a friend. When he saw me, he rose and we embraced. We began talking about various things, and the topic turned to mushrooms, which, it turned out, we both possessed at the time. We decided to take them together and proceeded to do so, munching them down wrapped in a slice of wheat bread.
In about 30 minutes, I began to feel the effects. Silence fell over me like a curtain. Speech seemed a profanity, to disturb such precious thought. I was moved by the beauty and comfort I experienced. I loved everyone and everything.  I stared at the tarp, undulating slightly in the perfect breeze, and heard their sweet voices, whispering assurances to me, sounding like heaven.
My attention was distracted and I glanced at the bamboo fence mentioned earlier. To my horror, it was not made of bamboo, but instead imaciated bodies of what appeared to be tiny people were aranged vertically and woven together in place of the sticks I had seen previously. Every nick and mark on the fence appeared to me to be tiny horrified faces, limp arms and legs, dark exposed crotches and breasts of these people who in my mind had been brutally killed and hen arranged in this way. Also, the bodies appears to be rotating counter-clockwise in a hypnotic anner. I saw in their suffering as the suffering inflicted universally by the strong upon the weak. Before me was the agony of the innocent in what appeared to be hell, and above me was the perfection of heaven. I am not a religous person, but the images I was witnessing were making me wonder. Could there be more to our world than I initially thought?
The object of my affections at the time (let's call him Jeff) asked me to go swimming with him. We made the journey along the sun-baked rocks, past the guard and weaved our way through the tents to the deep green river. I was scantilly clad and removed my sandals and walked in. The deliciously cool water enveloped my skin. It was the most wonderful experience I had ever had, and after a brief dip, he and I wandered back to his tent, retracing our steps to the guard post. There was a new person there who refused to let me in. All of my belongings and senses of comfort were within that campground. Rather than arguing with the woman, I let Jeff speak for me and I stared at the dust on the ground, dumb-struck that this person, in the face of such mind-bobbling beauty, could care about something like a wristband.
Jeff eventually convinced her to let me pass, and we walked back to the tent contemplating the insignificance of the woman’s protest. When we got back to the circle of tents, Jeff asked me to go into his tent with him, and I accepted. Bear in mind, it was about noon and 90 degrees in the shade at this point, and going into the sauna-esque tent was most appealing at that point. We retired to the air matress inside and began a long and meaningful talk about our current experience. We wound up intertwined and I naked, slipping in and out of consciousness. I can only guess it was the heat that caused it, but unlike the hyper-alertness I usually experience during a mushroom journey, I was totally lethargic.
A thought slinked into my mind. What if the kind stranger I had procured the mushrooms from had made a mistake? Could they have been deathcaps? I didn't know. I began focussing all of my energy on maintaining control of bodily functions. It was blindingly hot in the tent, so I kept my eyes closed for much of the time. I became acutely aware of this smell, highly unpleasant and mildly nauseating. I was sure that I was in some way responsible for it.
'Don't Die,' he said. My mind careened out of control. I knew I was dying. It had to be true, I respected Jeff's knowledge and opinion enough to know it had to be true. His fears were mine, and then it happened. The bright light appeared before me, overwhelming me with the glory of it. I heard voices speaking faintly in languages I didn't understand. I saw the faces of my family, smiling and bidding me a safe journey. It's all going to be okay, I thought. This is only one more step. Living, Dead, what does it matter? I am me, and I understand, I thought. It was like a bolt of lightning, and I felt it to my core.
I welcomed my own death, reaching out to it with open arms, longing to taste it, to experience something completely new. I was ready. I remained in this deeply meditative state for about an hour and a half, jostled from my dream-like trance by the noise of the camp around us. I heard voices of the other revelers outside the tent, whoops and laughs and raised voices. It was time to go rejoin society, I thought. I put my clothes on and someone opened the tent and we re-joined the gray and wasted world outside. I took with me the knowledge that I had confronted death, stared it in the face, embraced and explored the threshold and then returned to the world of the living unscathed. Any substance capable of allowing a person to leave themselves in this way is truly a gift from the divine.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


{% elif activity.status_type == 'Note' %}
{% include 'snippets/status_banner.html' %}
{{ activity.content | safe }}
{% for book in activity.mention_books.all %}
{% include 'snippets/book.html' with book=book size=large description=True %}
{% endfor %}
{% else %}
{# generic handling for a misc activity, which perhaps should not be displayed at all #}
did {{ activity.activity_type }}
{% endif %}


--- layout: post class: post-template title: "Plotting a ggtree and ggplots side by side" author: thackl cover: img/ggtree-composite-3.png categories: [R, genomics] ---
Plotting phylogenies and associated data side by side is a good way to explore evolutionary patterns in your data. In this post I will describe my approach for creating such plots in R using ggplot, ggtree, and patchwork.
ggtree itself comes with a few methods (gheatmap
, msaplot
, facet_plot
) to
display additional data next to the trees. Those methods, however, always
combine the data and the tree within the same plot area. This considerably
limits customizability. I, therefore, decided to go down a different route, and
combine multiple individual plots in order to retain a high degree of
customizability.
Let's start with a simple example. We need a dummy tree, and two dummy data sets that we want to plot. Both, tree and data use the same labels to refer to the different organisms.
library(tidyverse) library(ggtree) library(patchwork) # a tree set.seed(1338) tr <- rtree(10) # and some dummy data df1 <- tibble( # only some labels match label = c(tr$tip.label[sample(6, 6)], "u9", "v9"), value = label %>% str_sub(2) %>% as.numeric) df2 <- tibble( label = rep(tr$tip.label, 4), category = rep(1:4, each=10), value = rnorm(40, 0, 3)) no_legend <- function() theme(legend.position="none") # plot the tree, gg_tr <- ggtree(tr) + geom_tiplab(align=TRUE) + scale_x_continuous(expand=expand_scale(0.2)) # make more room for the labels # the data points, the histogram and the heatmap gg_hist <- ggplot(df1, aes(label, value)) + geom_col(aes(fill=substr(label, 1, 1))) + no_legend() gg_heat <- ggplot(df2, aes(category, label)) + geom_tile(aes(fill=value)) + scale_fill_gradient2() + no_legend() gg_tr + gg_hist + gg_heat + plot_annotation(tag_levels="A") ggsave("img/ggtree-composite-1.png", type='cairo', width=8, height=4)
So far so good. Now we want to reorder the data in the plots so it aligns with the leaves in our tree.
Under the hood, ggtrees are laid out on a numeric coordinate system. By default, the leaves match whole numbers, from 1 to the number of leaves. The easiest way to align data in other plots to the tree is to match the y-coordinates using common labels. So let's start with that.
tree_y()
is a little helper function that takes a ggtree and a data frame with
a label column. The function matches the ggtree and the data frame by the
label column and returns the new y-coordinates for the data. We will use this
function to transform the labels in our data on-the-fly in the ggplot aesthetics
argument.
tree_y <- function(ggtree, data){ if(!inherits(ggtree, "ggtree")) stop("not a ggtree object") left_join(select(data, label), select(ggtree$data, label, y)) %>% pull(y) } # replot histogram and heatmap, match the y-coords to the tree gg_hist <- ggplot(df1, aes(tree_y(gg_tr, df1), value)) + geom_col(aes(fill=substr(label, 1, 1))) + no_legend() + coord_flip() # flip this plot gg_heat <- ggplot(df2, aes(category, y=tree_y(gg_tr, df2))) + geom_tile(aes(fill=value)) + scale_fill_gradient2() + no_legend() gg_tr + gg_hist + gg_heat + plot_annotation(tag_levels="A") ggsave("img/ggtree-composite-2.png", type='cairo', width=8, height=4)
OK, this doesn't look bad at all. The data in all plots is now reordered and matches the order of the tree leaves. However, it doesn't align properly yet. That has two reasons:
First, the plotted data have different y-limits: our first data set is missing data for the top tree leaf (t8), and in the heat map the tiles are centered around the leaf y-coordinates, and actually extend outwards by 0.5 units.
Second, the different plots also have different amounts of expansion space around their outer data points. This is a ggplot feature, and explained under the expand argument of the continuous scales: "The defaults are to expand the scale by 5% on each side for continuous variables, and by 0.6 units on each side for discrete variables".
To address those two related issues, we need a way to control the y-limits and the expansion space around it for the tree and the plots. For the tree, it's quite simple. All we need to do is settle on a fixed expansion space that gives enough room for leaf-centered objects such as tiles and bars in aligned plots. We don't have to do anything about the y-limits of the tree, because those are our reference.
scale_y_tree()
is a simple wrapper around scale_y_continuous()
, that when
applied to the ggtree plot, resets the expansion space around the tree limits to
0.6 units on each side of the leaves.
For the plots, it's a bit more involved, because we want to derive the y-limits
from the tree, rather than data. The way I made it work is by writing the
wrapper function ggtreeplot()
. The function basically behaves like ggplot()
,
but take a ggtree as an additional argument. It uses the ggtree to a) match the
y-coordinates of the data by common labels (just as we did on-the-fly for the
previous plots), and b) it computes new y-limits from the tree and adds those
and our predefined expansion space of 0.6 to the plot.
The flip
parameter is necessary when x and y in the plot will be
flipped. Because in that case, we need to set our limits internally on the
x-axis, which will later become the y-axis.
# overwrite the default expand for continuous scales scale_y_tree <- function(expand=expand_scale(0, 0.6), ...){ scale_y_continuous(expand=expand, ...) } # get the range of the ggtree y-axis data tree_ylim <- function(ggtree){ if(!inherits(ggtree, "ggtree")) stop("not a ggtree object") range(ggtree$data$y) } # plot data next to a ggtree aligned by shared labels ggtreeplot <- function(ggtree, data = NULL, mapping = aes(), flip=FALSE, expand_limits=expand_scale(0,.6), ...){ if(!inherits(ggtree, "ggtree")) stop("not a ggtree object") # match the tree limits limits <- tree_ylim(ggtree) limits[1] <- limits[1] + (limits[1] * expand_limits[1]) - expand_limits[2] limits[2] <- limits[2] + (limits[2] * expand_limits[3]) + expand_limits[4] if(flip){ mapping <- modifyList(aes_(x=~x), mapping) data <- mutate(data, x=tree_y(ggtree, data)) gg <- ggplot(data=data, mapping = mapping, ...) + scale_x_continuous(limits=limits, expand=c(0,0)) }else{ mapping <- modifyList(aes_(y=~y), mapping) data <- mutate(data, y=tree_y(ggtree, data)) gg <- ggplot(data=data, mapping = mapping, ...) + scale_y_continuous(limits=limits, expand=c(0,0)) } gg } # get rid of superfluous axis - this works after coord_flip, so it also works # for the rotated histogram no_y_axis <- function () theme(axis.line.y = element_blank(), axis.title.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank())
Now we can plot our tree and the data side by side using our new functions. We
plot the tree as before but add the fixed y scale. For the data, we replace the
ggplot()
call with the ggtreeplot()
call. Setting the y-aesthetic (or x in
case of flipped plots) is no longer necessary. ggplotree()
assumes that it
should point to the coordinates we got from matching the labels from the data to
the tree.
gg_tr <- ggtree(tr) + geom_tiplab(align=TRUE) + scale_x_continuous(expand=expand_scale(0.2)) + # make more room for the labels scale_y_tree() gg_hist <- ggtreeplot(gg_tr, df1, aes(y=value), flip=TRUE) + geom_col(aes(fill=substr(label, 1, 1))) + no_legend() + coord_flip() + no_y_axis() gg_heat <- ggtreeplot(gg_tr, df2, aes(x=category)) + geom_tile(aes(fill=value)) + scale_fill_gradient2() + no_legend() + no_y_axis() gg_tr + gg_hist + gg_heat + plot_annotation(tag_levels="A") ggsave("img/ggtree-composite-3.png", type='cairo', width=8, height=4)
Et voilà! A tree and two beautiful plots, side by side, and perfectly aligned. The grammar for this final plot is pretty much identical to what we used for the initial unaligned ggtree/ggplots. This makes it very easy to go from a set of generic plots to this composite plot. At the same time, we retain the level modularity and customizability that we had with the original ggplots. This, in my opinion, is what makes this approach powerful.


{{ keyword }}
TOGGLE
PRESS
ON
OFF
METHOD
{{theColour}}
Search text
Posted by {{post.author}}
{{post.title}}


This document describes the new PB protocol. This is a layer on top of Banana which provides remote object access (method invocation and instance transfer).
Fundamentally, PB is about one side keeping a
RemoteReference
to the other side's Referenceable
. The
Referenceable has some methods that can be invoked remotely: functionality
it is offering to remote callers. Those callers hold RemoteReferences which
point to it. The RemoteReference object offers a way to invoke those methods
(generally through the callRemote
method).
There are plenty of other details, starting with how the RemoteReference is obtained, and how arguments and return values are communicated.
For the purposes of this document, we will designate the side that holds
the actual Referenceable
object as local
, and the side
that holds the proxy RemoteReference
object as remote
.
This distinction is only meaningful with respect to a single
RemoteReference/Referenceable pair. One program may hold Referenceable
A
and RemoteReference B
, paired with another that holds
RemoteReference A
and Referenceable B
. Once initialization is
complete, PB is a symmetric protocol.
It is helpful to think of PB as providing a wire or pipe that connects
two programs. Objects are put into this pipe at one end, and something
related to the object comes out the other end. These two objects are said to
correspond to each other. Basic types (like lists and dictionaries) are
handled by Banana, but more complex types (like instances) are treated
specially, so that most of the time there is a native
form (as
present on the local side) that goes into the pipe, and a remote form that
comes out.
The PB session begins with some feature negotiation and (generally) the receipt of a VocabularyDict. Usually this takes place over an interactive transport, like a TCP connection, but newpb can also be used in a more batched message-oriented mode, as long as both the creator of the method call request and its eventual consumer are in agreement about their shared state (at least, this is the intention.. there are still pieces that need to be implemented to make this possible).
The local side keeps a table which provides a bidirectional mapping
between Referenceable
objects and a connection-local
object-ID
number. This table begins with a single object called the
Root
, which is implicitly given ID number 0. Everything else is
bootstrapped through this object. For the typical PB Broker, this root
object performs cred authentication and returns other Referenceables as the
cred Avatar.
The remote side has a collection of RemoteReference
objects,
each of which knows the object-ID of the corresponding Referenceable, as
well as the Broker which provides the connection to the other Broker. The
remote side must do reference-tracking of these RemoteReferences, because as
long as it remains alive, the local-side Broker must maintain a reference to
the original Referenceable.
The remote side invokes a remote method by calling
ref.callRemote()
on its RemoteReference. This starts by
validating the method name and arguments against a Schema
(described
below). It then creates a new Request object which will live until the method
call has either completed successfully or failed due to an exception
(including the connection being lost). callRemote
returns a
Deferred, which does not fire until the request is finished.
It then sends a call
banana sequence over the wire. This
sequence indicates the request ID (used to match the request with the
resulting answer
or error
response), the object ID
of the Referenceable being targeted, a string to indicate the name of the
method being invoked, and the arguments to be passed into the method.
All arguments are passed by name (i.e. keyword arguments instead of
positional parameters). Each argument is subject to the argument
transformation
described below.
The local side receives the call
sequence, uses the object-ID
to look up the Referenceable, finds the desired method, then applies the
method's schema to the incoming arguments. If they are acceptable, it invokes
the method. A normal return value it sent back immediately in an
answer
sequence (subject to the same transformation as the
inbound arguments). If the method returns a Deferred, the answer will be sent
back when the Deferred fires. If the method raises an exception (or the
Deferred does an errback), the resulting Failure is sent back in a
error
sequence. Both the answer
and the
error
start with the request-ID so they can be used to complete
the Request object waiting on the remote side.
The original Deferred (the one produced by callRemote
) is
finally callbacked with the results of the method (or errbacked with a
Failure or RemoteFailure object).
This code runs on the local
side: the one with the
pb.Referenceable
which will respond to a remote invocation.
class Responder(pb.Referenceable): def remote_add(self, a, b): return a+b
and the following code runs on the remote
side (the one which holds
a pb.RemoteReference
):
def gotAnswer(results): print results d = rr.callRemote("add", a=1, b=2) d.addCallback(gotAnswer)
Note that the arguments are passed as named parameters: oldpb used both positional parameters and named (keyword) arguments, but newpb prefers just the keyword arguments. TODO: newpb will probably convert positional parameters to keyword arguments (based upon the schema) before sending them to the remote side.
To nail down the types being sent across the wire, you can use a
RemoteInterface
to define the methods that are implemented by
any particular pb.Referenceable
:
class RIAdding(pb.RemoteInterface): def add(a=int, b=int): return int class Responder(pb.Referenceable): implements(RIAdding) def remote_add(self, a, b): return a+b # and on the remote side: d = rr.callRemote(RIAdding['add'], a=1, b=2) d.addCallback(gotAnswer)
In this example, the RIAdding
remote interface defines a single
method add
, which accepts two integer parameters and returns an
integer. This method (technically a classmethod) is used instead of the
string form of the method name. What does this get us?
remote_add
does not need to worry about what strange types
it might be given, such as two strings, or two lists.gotAnswer
callback function) does not need to worry about what
strange type the remote method returns.You can use either technique: with RemoteInterfaces or without. To get the type-checking benefits, you must use them. If you do not, PB cannot protect you against memory consumption attacks.
RemoteInterfaces are passed by name. Each side of a PB connection has a
table which maps names to RemoteInterfaces (subclasses of
pb.RemoteInterface
). Metaclass magic is used to add an entry to
this table each time you define a RemoteInterface subclass, using the
__remote_name__
attribute (or reflect.qual() if that is not
set).
Each Referenceable
that goes over the wire is accompanied by
the list of RemoteInterfaces which it claims to implement. On the receiving
side, these RemoteInterface names are looked up in the table and mapped to
actual (local) RemoteInterface classes.
TODO: it might be interesting to serialize the RemoteInterface class and ship it over the wire, rather than assuming both sides have a copy (and that they agree). However, if one side does not have a copy, it is unlikely that it will be able to do anything very meaningful with the remote end.
The syntax of RemoteInterface is still in flux. The basic idea is that
each method of the RemoteInterface defines a remotely invokable method,
something that will exist with a remote_
prefix on any
pb.Referenceable
s which claim to implement it.
Those methods are defined with a number of named parameters. The default
value of each parameter is something which can be turned into a
Constraint
according to the rules of schema.makeConstraint .
This means you can use things like (int, str, str)
to mean a
tuple of exactly those three types.
Note that the methods of the RemoteInterface do not list
self
as a parameter. As the zope.interface documentation points out,
self
is an implemenation detail, and does not belong in the interface
specification. Another way to think about it is that, when you write the code
which calls a method in this interface, you don't include self
in the
arguments you provide, therefore it should not appear in the public
documentation of those methods.
The method is required to return a value which can be handled by schema.makeConstraint: this constraint is then applied to the return value of the remote method.
Other attributes of the method (perhaps added by decorators of some sort) will, some day, be able to specify specialized behavior of the method. The brainstorming sessions have come up with the following ideas:
We are also considering how to merge the RemoteInterface with other useful interface specifications, in particular zope.interface and formless.TypedInterface .
To understand this section, it may be useful to review the Banana documentation on serializing object graphs. Also note that method arguments and method return values are handled identically.
Basic types (lists, tuples, dictionaries) are serialized and unserialized
as you would expect: the resulting object would (if it existed in the
sender's address space) compare as equal (but of course not
identical
, because the objects will exist at different memory
locations).
Shared references to the same object are handled correctly. Banana is responsible for noticing that a sharable object has been serialized before (or at least has begun serialization) and inserts reference markers so that the object graph can be reconstructed. This introduces the concept of serialization scope: the boundaries beyond which shared references are not maintained.
For PB, serialization is scoped to the method call. If an object is referenced by two arguments to the same method call, that method will see two references to the same object. If those arguments are containers of some form, which (eventually) hold a reference to the same object, the object graph will be preserved. For example:
class Caller: def start(self): obj = [1, 2, 3] self.remote.callRemote("both", obj, obj) self.remote.callRemote("deeper", ["a", obj], (4, 5, obj)) class Called(pb.Referenceable): def remote_both(self, arg1, arg2): assert arg1 is arg2 assert arg1 == [1,2,3] def remote_deeper(self, listarg, tuplearg): ref1 = listarg[1] ref2 = tuplearg[2] assert ref1 is ref2 assert ref1 == [1,2,3]
But if the remote-side object is referenced in two distinct remote method invocations, the local-side methods will see two separate objects. For example:
class Caller: def start(self): self.obj = [1, 2, 3] d = self.remote.callRemote("one", self.obj) d.addCallback(self.next) def next(self, res): self.remote.callRemote("two", self.obj) class Called(pb.Referenceable): def remote_one(self, ref1): assert ref1 == [1,2,3] self.ref1 = ref1 def remote_two(self, ref2): assert ref2 == [1,2,3] assert ref1 is not ref2 # not the same object
You can think of the method call itself being a node in the object graph, with the method arguments as its children. The method call node is picked up and the resulting sub-tree is serialized with no knowledge of anything outside the sub-treeThis isn't quite true: for some objects, serialization is scoped to the connection as a whole. Referenceables and RemoteReferences are like this..
The value returned by a method call is serialized by itself, without reference to the arguments that were given to the method. If a remote method is called with a list, and the method returns its argument unchanged, the caller will get back a deep copy of the list it passed in.
Referenceables are transformed into RemoteReferences when they are sent
over the wire. As one side traverses the object graph of the method arguments
(or the return value), each Referenceable
object it encounters
it serialized with a my-reference
sequence, that includes the
object-ID number. When the other side is unserializing the token stream, it
creates a RemoteReference
object, or uses one that already
exists.
Likewise, if an argument (or return value) contains a
RemoteReference
, and it is being sent back to the Broker that
holds the original Referenceable
then it will be turned back
into that Referenceable when it arrives. In this case, the caller of a
remote method which returns its argument unchanged will see a a
result that is identical to what it passed in:
class Target(pb.Referenceable): pass class Caller: def start(self): self.obj = Target() d = self.remote.callRemote("echo", self.obj) d.addCallback(self.next) def next(self, res): assert res is self.obj class Called(pb.Referenceable): def remote_echo(self, arg): # arg is a RemoteReference to a Target() instance return arg
These references have a serialization scope which extends across the
entire connection. As long as two method calls share the same
Broker
instance (which generally means they share the same TCP
socket), they will both serialize Referenceable
s into identical
RemoteReference
s. This also means that both sides do
reference-counting to insure that the Referenceable doesn't get
garbage-collected while a remote system holds a RemoteReference that points
to it.
In the future, there may be other classes which behave this way. In
particular, Referenceable
and Callable
may be distinct
qualities.
Some objects can be marked to indicate that they should be copied bodily
each time they traverse the wire (pass-by-value instead of
pass-by-reference). Classes which inherit from pb.Copyable
are
passed by value. Their getTypeToCopy
and
getStateToCopy
methods are used to assemble the data that will
be serialized. These methods default to plain old reflect.qual
(which provides the fully-qualified name of the class) and the instance's
attribute __dict__
. You can override these to provide a
different (or smaller) set of state attributes to the remote end.
class Source(pb.Copyable): def getStateToCopy(self): state = self.__dict__.copy() del state['private'] state['children'] = [] return state
Rather than subclass pb.Copyable
, you can also implement the
flavors.ICopyable
interface:
from twisted.python import reflect class Source2: implements(flavors.ICopyable) def getTypeToCopy(self): return reflect.qual(self.__class__) def getStateToCopy(self): return self.__dict__
.. or register an ICopyable adapter. Using the adapter allows you to
define serialization behavior for third-party classes that are out of your
control (ones which you cannot rewrite to inherit from
pb.Copyable
).
class Source3: pass class Source3Copier: implements(flavors.ICopyable) def getTypeToCopy(self): return 'foo.Source3' def getStateToCopy(self): orig = self.original d = { 'foo': orig.foo, 'bar': orig.bar } return d registerAdapter(Source3Copier, Source3, flavors.ICopyable)
On the other end of the wire, the receiving side must register a
RemoteCopy
subclass under the same name as returned by the
sender's getTypeToCopy
value. This subclass is used as a factory
to create instances that correspond to the original Copyable
.
The registration can either take place explicitly (with
pb.registerRemoteCopy
), or automatically (by setting the
copytype
attribute in the class definition).
The default RemoteCopy
behavior simply sets the instance's
__dict__
to the incoming state, which may be plenty if you are
willing to let outsiders arbitrarily manipulate your object state. If so, and
you believe both peers are importing the same source file, it is enough to
create and register the RemoteCopy
at the same time you create
the Copyable
:
class Source(pb.Copyable): def getStateToCopy(self): state = self.__dict__.copy() del state['private'] state['children'] = [] return state class Remote(pb.RemoteCopy): copytype = reflect.qual(Source)
You can do something special with the incoming object state by overriding
the setCopyableState
method. This may allow you to do some
sanity-checking on the state before trusting it.
class Remote(pb.RemoteCopy): def setCopyableState(self, state): state['count'] = 0 self.__dict__ = state self.total = self.one + self.two # show explicit registration, instead of using 'copytype' class attribute pb.registerRemoteCopy(reflect.qual(Source), Remote)
You can also set a constraint on the inbound object state, which provides a way to enforce some type checking on the state components as they arrive. This protects against resource-consumption attacks where someone sends you a zillion-byte string as part of the object's state.
class Remote(pb.RemoteCopy): stateSchema = schema.AttributeDictConstraint(('foo', int), ('bar', str))
In this example, the object will only accept two attributes: foo
(which must be a number), and bar
(which must be a string shorter than
the default limit of 1000 characters). Various classes from the
schema
module can be used to construct more complicated
constraints.
Each object gets Sliced
into a stream of tokens as they go over the
wire: Referenceable and Copyable are merely special cases. These classes have
Slicers which implement specific behaviors when the serialization process is
asked to send their instances to the remote side. You can implement your own
Slicers to take complete control over the serialization process. The most
useful reason to take advantage of this feature is to implement streaming
slicers
, which can minimize in-memory buffering by only producing Banana
tokens on demand as space opens up in the transport.
Banana Slicers are documented in detail in the Banana documentation. Once you create a Slicer class,
you will want to register
it, letting Banana know that this Slicer is
useful for conveying certain types of objects across the wire. The registry
maps a type to a Slicer class (which is really a slicer factory), and is
implemented by registering the slicer as a regular adapter
for the
ISlicer
interface. For example, lists are serialized by the
ListSlicer
class, so ListSlicer
is registered as
the slicer for the list
type:
class ListSlicer(BaseSlicer): opentype = ("list",) slices = list
Slicer registration can be either explicit or implicit. In this example,
an implicit registration is used: by setting the slices
attribute to
the list
type, the BaseSlicer's metaclass automatically
registers the mapping from list
to ListSlicer.
To explicitly register a slicer, just leave opentype
set to
None (to disable auto-registration), and then register the slicer
manually.
class TupleSlicer(BaseSlicer): opentype = ("tuple",) slices = None ... registerAdapter(TupleSlicer, tuple, pb.ISlicer)
As with ICopyable, registering an ISlicer adapter allows you to define exactly how you wish to serialize third-party classes which you do not get to modify.
On the other side of the wire, the incoming token stream is handed to an
Unslicer
, which is responsible for turning the set of tokens
into a single finished object. They are also responsible for enforcing limits
on the types and sizes of the tokens that make up the stream. Unslicers are
also described in greater detail in the Banana
docs.
As with Slicers, Unslicers need to be registered to be useful. This
registry maps opentypes
to Unslicer classes (i.e. factories which can
produce an unslicer instance each time the given opentype appears in the
token stream). Therefore it maps tuples to subclasses of
BaseUnslicer
.
Again, this registry can be either implicit or explicit. If the Unslicer
has a non-None class attribute named opentype
, then it is
automatically registered. If it does not have this attribute (or if it is set
to None), then no registration is performed, and the Unslicer must be
manually registered:
class MyUnslicer(BaseUnslicer): ... pb.registerUnslicer(('myopentype',), MyUnslicer)
Also remember that this registry is global, and that you cannot register two Unslicers for the same opentype (you'll get an exception at class-definition time, which will probably result in an ImportError).
The simplest kind of slicer has a sliceBody
method (a
generator) which yields a series of tokens. To demonstrate how to build a
useful Slicer, we'll write one that can send large strings across the wire in
pieces. Banana can send arbitrarily long strings in a single token, but each
token must be handed to the transport layer in an indivisble chunk, and
anything that doesn't fit in the transmit buffers will be stored in RAM until
some space frees up in the socket. Practically speaking, this means that
anything larger than maybe 50kb will spend a lot of time in memory,
increasing the RAM footprint for no good reason.
Because of this, it is useful to be able to send large amounts of data in smaller pieces, and let the remote end reassemble them. The following Slicer is registered to handle all open files (perhaps not the best idea), and simply emits the contents in 10kb chunks.
(readers familiar with oldpb will notice that this Slicer/Unslicer pair provide similar functionality to the old FilePager class. The biggest improvement is that newpb can accomplish this without the extra round-trip per chunk. The downside is that, unless you enable streaming in your Broker, no other methods can be invoked while the file is being transmitted. The upside of the downside is that this lets you retain in-order execution of remote methods, and that you don't have to worry changes to the contents of the file causing corrupt data to be sent over the wire. The oter upside of the downside is that, if you enable streaming, you can do whatever other processing you wish between data chunks.)
class BigFileSlicer(BaseSlicer): opentype = ("bigfile",) slices = types.FileType CHUNKSIZE = 10000 def sliceBody(self, streamable, banana): while 1: chunk = self.obj.read(self.CHUNKSIZE) if not chunk: return yield chunk
To receive this, you would use the following minimal Unslicer at the other end. Note that this Unslicer does not do as much as it could in the way of constraint enforcement: an attacker could easily make you consume as much memory as they wished by simply sending you a never-ending series of chunks.
class BigFileUnslicer(LeafUnslicer): opentype = ("bigfile",) def __init__(self): self.chunks = [] def checkToken(self, typebyte, size): if typebyte != tokens.STRING: raise BananaError("BigFileUnslicer only accepts strings") def receiveChild(self, obj): self.chunks.append(obj) def receiveClose(self): return "".join(self.chunks)
The opentype
attribute causes this Unslicer to be implicitly
registered to handle any incoming sequences with an index tuple
of
("bigfile",)
, so each time BigFileSlicer is used, a
BigFileUnslicer will be created to handle the results.
A more complete example would want to write the file chunks to disk at they arrived, or process them incrementally. It might also want to have some way to limit the overall size of the file, perhaps by having the first chunk be an integer with the promised file size. In this case, the example might look like this somewhat contrived (and somewhat insecure) Unslicer:
class SomewhatLargeFileUnslicer(LeafUnslicer): opentype = ("bigfile",) def __init__(self): self.fileSize = None self.size = 0 self.output = open("/tmp/bigfile.txt", "w") def checkToken(self, typebyte, size): if self.fileSize is None: if typebyte != tokens.INT: raise BananaError("fileSize must be an INT") else: if typebyte != tokens.STRING: raise BananaError("BigFileUnslicer only accepts strings") if self.size + size > self.fileSize: raise BananaError("size limit exceeded") def receiveChild(self, obj): if self.fileSize is None: self.fileSize = obj # decide if self.fileSize is too big, raise error to refuse it else: self.output.write(obj) self.size += len(obj) def receiveClose(self): self.output.close() return open("/tmp/bigfile.txt", "r")
This constrained BigFileUnslicer uses the fact that each STRING token comes with a size, which can be used to enforce the promised filesize that was provided in the first token. The data is streamed to a disk file as it arrives, so no more than CHUNKSIZE of memory is required at any given time.
TODO: add example
The following slicer will, when the broker allows streaming, will yield the CPU to other reactor events that want processing time. (This technique becomes somewhat inefficient if there is nothing else contending for CPU time, and if this matters you might want to use something which sends N chunks before yielding, or yields only when some other known service announces that it wants CPU time, etc).
class BigFileSlicer(BaseSlicer): opentype = ("bigfile",) slices = types.FileType CHUNKSIZE = 10000 def sliceBody(self, streamable, banana): while 1: chunk = self.obj.read(self.CHUNKSIZE) if not chunk: return yield chunk if streamable: d = defer.Deferred() reactor.callLater(0, d.callback, None) yield d
The next example will deliver data as it becomes available from a hypothetical slow process.
class OutputSlicer(BaseSlicer): opentype = ("output",) def sliceBody(self, streamable, banana): assert streamable # requires it while 1: if self.process.finished(): return chunk = self.process.read(self.CHUNKSIZE) if not chunk: d = self.process.waitUntilDataIsReady() yield d else: yield chunk
Streamability is required in this example because otherwise the Slicer is required to provide chunks non-stop until the object has been completely serialized. If the process cannot deliver data, it's not like the Slicer can block waiting until it becomes ready. Prohibiting streamability is done to ensure coherency of serialized state, and the only way to guarantee this is to not let any non-Banana methods get CPU time until the object has been fully processed.
On the receiving side, the Unslicer can be made streamable too. This is considerably easier than on the sending side, because there are fewer concerns about state coherency.
A streaming Unslicer is merely one that delivers some data directly from
the receiveChild
method, rather than accumulating it until the
receiveClose
method. The SomewhatLargeFileUnslicer example from
above is actually a streaming Unslicer. Nothing special needs to be
done.
On the other hand, it can be tricky to know where exactly to deliver the
data being streamed. The streamed object is probably part of a larger
structure (like a method call), where the higher-level attribute can be used
to determine which object or method should be called with the incoming data
as it arrives. The current Banana model is that each completed object (as
returned by the child's receiveClose
method) is handed to the
parent's receiveChild
method. The parent can do whatever it
wants with the results. To make streaming Unslicers more useful, the parent
should be able to set up a target for the data at the time the child
Unslicer is created.
More work is needed in this area to figure out how this functionality should be exposed.
Arbitrary instances (that is, anything which does not have an
ISlicer
adapter) are not serialized. If an argument to
a remote method contains one, you will get a Violation exception when you
attempt to serialize it (i.e., the Deferred that you get from
callRemote
will errback with a Failure that contains a
Violation exception). If the return value contains one, the Violation will
be logged on the local side, and the remote caller will see an error just as
if your method had raised a Violation itself.
There are two reasons for this. The first is a security precaution: you must explicitly mark the classes that are willing to reveal their contents to the world. This reduces the chance of leaking sensitive information.
The second is because it is not actually meaningful to send the contents of an arbitrary object. The recipient only gets the class name and a dictionary with the object's state. Which class should it use to create the corresponding object? It could attempt to import one based upon the classname (the approach pickle uses), but that would give a remote attacker unrestricted access to classes which could do absolutely anything: very dangerous.
Both ends must be willing to transport the object. The sending side
expresses this by marking the class (subclassing Copyable, or registering an
ISlicer adapter). The receiving side must register the class as well, by
doing registerUnslicer or using the opentype
attribute in a
suitable Unslicer subclass definition.
There are several Banana sequences which are used to support the RPC mechanisms of Perspective Broker. These are in addition to the usual ones listed in the Banana docs.
These sequences only appear at the top-level (never inside another object).
| PB (method call) Sequences | |
method call (callRemote ) |
OPEN(call) INT(request-id) INT/STR(your-reference-id) STRING(interfacename) STRING(methodname) (STRING(argname),argvalue).. CLOSE |
| method response (success) | OPEN(answer) INT(request-id) value CLOSE |
| method response (exception) | OPEN(error) INT(request-id) value CLOSE |
| RemoteReference.__del__ | OPEN(decref) INT(your-reference-id) CLOSE |
The following sequences are used to serialize PB-specific objects. They never appear at the top-level, but only as the argument value or return value (or somewhere inside them).
| PB (method call) Sequences | |
| pb.Referenceable | OPEN(my-reference) INT(clid) [OPEN(list) InterfaceList.. CLOSE] CLOSE |
| pb.RemoteReference | OPEN(your-reference) INT/STR(clid) CLOSE |
| pb.Copyable | OPEN(copyable) STRING(reflect.qual(class)) (attr,value).. CLOSE |
The first time a pb.Referenceable
is sent, the second object
is an InterfaceList, which is a list of interfacename strings, and therefore
constrainable by a schema of ListOf(str) with some appropriate
maximum-length restrictions. This InterfaceList describes all the Interfaces
that the corresponding pb.Referenceable
implements. The
receiver uses this list to look up local Interfaces (and therefore Schemas)
to attach to the pb.RemoteReference
. This is how method schemas
are checked on the sender side.
This implies that Interfaces must be registered, just as classes are for
pb.Copyable
. TODO: what happens if an unknown Interface is
received?
Classes which wish to be passed by value should either inherit from
pb.Copyable
or have an ICopyable
adapter
registered for them. On the receiving side, the
registerRemoteCopy
function must be used to register a factory,
which can be a pb.RemoteCopy
subclass or something else which
implements IRemoteCopy
.
Failure
objects are sent as a pb.Copyable
with
a class name of twisted.python.failure.Failure
.
The side which holds the Referenceable
uses a
ReferenceableSlicer to serialize it. Each Referenceable
is
tracked with a process-Unique ID
(abbreviated puid
). As the
name implies, this number refers to a specific object within a given
process: it is scoped to the process (and is never sent to another process),
but it spans multiple PB connections (any given object will have the same
puid
regardless of which connection is referring to it). The
puid
is an integer, normally obtained with
id(obj)
, but you can override the object's
processUniqueID
method to use something else (this might be
useful for objects that are really proxies for something else). Any two
objects with the same puid
are serialized identically.
All Referenceables sent over the wire (as arguments or return values for
remote methods) are given a connection-local ID
(clid
)
which is scoped to one end of the connection. The Referenceable is serialized
with this number, using a banana sequence of (OPEN "my-reference"
clid)
. The remote peer (the side that holds the
RemoteReference
) knows the Referenceable
by the
clid
sent to represent it. These are small integers. From a
security point of view, any object sent across the wire (and thus given a
clid
) is forever accessible to the remote end (or at least until
the connection is dropped).
The sending side uses the Broker.clids
dict to map
puid
to clid
. It uses the
Broker.localObjects
dict to map clid
to
Referenceable
. The reference from .localObjects
also has the side-effect of making sure the Referenceable doesn't go out of
scope while the remote end holds a reference.
Broker.currentLocalID
is used as a counter to create
clid
values.
In response to the incoming my-reference
sequence, the
receiving side creates a RemoteReference
that remembers its
Broker and the clid
value. The RemoteReference is stashed in the
Broker.remoteReferences
weakref dictionary (which maps from
clid
to RemoteReference
), to make sure that a
single Referenceable
is always turned into the same
RemoteReference
. Note that this is not infallible: if the
recipient forgets about the RemoteReference
, PB will too. But if
they really do forget about it, then they won't be able to tell that the
replacement is not the same as the originalunless they
do something crazy like remembering the id(obj)
of the old
object and check to see if it is the same as that of the new one. But
id(obj)
is only unique among live objects anyway. It will
have a different clid
.and note that I
think there is a race condition here, in which the reference is sent over the
wire at the same time the other end forgets about it
This RemoteReference
is where the .callRemote
method lives. When used to invoke remote methods, the clid
is
used as the second token of a call
sequence. In this context,
the clid
is a your-reference
: it refers to the
recipient's .localObjects
table. The
Referenceable
-holder's my-reference-id
is sent
back to them as the your-reference-id
argument of the
call
sequence.
The RemoteReference
isn't always used to invoke remote
methods: it could appear in an argument or a return value instead: the goal
is to have the Referenceable
-holder see their same
Referenceable
come back to them. In this case, the
clid
is used in a (OPEN "your-reference" clib)
sequence. The Referenceable
-holder looks up the
clid
in their .localObjects
table and puts the
result in the method argument or return value.
In addition to the implicitly-created numerically-indexed
Referenceable
instances (kept in the Broker's
.localObjects
dict), there are explicitly-registered
string-indexed Referenceable
s kept in the PBServerFactory's
localObjects
dictionary. This table is used to publish objects
to the outside world. These objects are the targets of the
pb.getRemoteURL
and pb.callRemoteURL
functions.
To access these, a URLRemoteReference
must be created that
refers to a string clid
instead of a numeric one. This is a
simple subclass of RemoteReference
: it behaves exactly the same.
The URLRemoteReference
is created manually by
pb.getRemoteURL
, rather than being generated automatically upon
the receipt of a my-reference
sequence. It also assumes a list
of RemoteInterface names (which are usually provided by the holder of the
Referenceable
).
To invoke methods on a URL-indexed object, a string token is used as the
clid
in the your-reference-id
argument of a
call
sequence.
In addition, the clid
of a your-reference
sequence can be a string to use URL-indexed objects as arguments or return
values of method invocations. This allows one side to send a
URLRemoteReference
to the other and have it turn into the
matching Referenceable
when it arrives. Of course, if it is
invalid, the method call that tried to send it will fail.
Note that these URLRemoteReference
objects wil not survive a
roundtrip like regular RemoteReference
s do. The
URLRemoteReference
turns into a Referenceable
, but
the Referenceable
will turn into a regular numeric (implicit)
RemoteReference
when it comes back. This may change in the
future as the URL-based referencing scheme is developed. It might also
become possible for string clid
s to appear in
my-reference
sequences, giving
Referenceable
-holders the ability to publish URL references
explicitly.
It might also become possible to have these URLs point to other servers.
In this case, a remote
sequence will probably be used, rather
than the my-reference
sequence used for implicit
references.
Note that these URL-endpoints are per-Factory, so they are shared between
multiple connections (the implicitly-created references are only available
on the connection that created them). The PBServerFactory is created with a
root object
, which is a URL-endpoint with a clid
of an
empty string.


You cannot undo this action." %}


Global Aeromodelling Championship is a unique opportunity to connect the youth and lay the foundation for quality aero education. The event will focus on technologies related to aviation and aerospace. The participants of the program will have a chance to interact with leaders focusing especially on sustainable aerospace innovations.
The dates of the final event will fall between 15th of April 2021 to 5th of May, 2021. The entire session will be happening virtually.
Register by paying the fee at our event link
Print out the one sheet plane model given in the email and colour it creatively
Fold the plane by following our video instructions
Upload a video of your flying plane
Register by paying the fee at our event link
Check your inbox and WhatsApp for our instructions email within 24 hours
Print out the one sheet plane model given in the email and colour it creatively
Fold the plane by following our video instructions
Upload a video of your flying plane (YouTube /Google Drive/Facebook etc.)
Watch out for our update and you could be one of our top contestants!
The contest is open to Indian nationals.
The contestants are hereby required to adhere to all the rules announced by the organisers.
Parental guidance may be required for younger kids.
The decision of the judges are final and binding.
Certificate of Participation by AIC RAISE
Access to Premium Aeromodelling Course on GradRaise.com
Global K12 Aero Club Community Membership from AirNCraft
Attractive Prizes for all age groups
Special Vouchers from ActiveDabba
Special invite for upcoming events
The Event is organised by ActiveDabba.com in association with AIC RAISE.
AIC RAISE is India's 1st Startup Incubation Centre focusing on the United Nation's Sustainable Development Goals and established under Atal Innovation Mission of NITI Aayog, Government of India.
Active Dabba is our exclusive online store for creative S.T.E.M activity boxes involving themes like Crafts and Aeromodelling. These kits are tested and approved by age-appropriate users across countries. Every activity kit has certain value adds and surprise games based on the age category of the user.
SDG School is a UN SDGs education initiative launched by Indian and Syrian volunteers with an aim to build and raise awareness about the UN's Sustainable Development Goals to make the world a better place. We believe that working collaboratively, locally and globally, will help to achieve the Global Goals before 2030. We start from each community's need, then we create a plan of action that includes individuals and groups of this community.
18/57 A/1, Jai Nagar,
Kavundampalayam,
Coimbatore - 641 030,
Tamil Nadu
+91 422 43 80 500
Event Information /
Feedback & Sponsorship Enquiries
+91 78 458 02 872


| Code | Line | Column | Evidence | Reason |
|---|---|---|---|---|
| D:\repo-github\mashupjs.vs2013\src\Mashup.UI.Core\dist\app.js | ||||
| W101 | 1 | 253 | // ALL GOOD IF NO ERRORS BELOW THIS LINE - I'm leaving this in the code to force the gulp-jshint-html-reporter pligin to update the html file. If there are no errors then no report is written so you never know if your last JSHint error is fixed or not. |
Line is too long. |


--- layout: default title: Matthews Blog ---
Hi, My name is Matthew. I have recently graduated and obtained an Advanced Diploma in Computer Programming and Analysis at Seneca College. I love to work on software projects. My main interests include: coding, web development, open-source software development, computer hardware, game development, virtual reality, and more!


Any organized collection of information used to understand or solve a problem is called data. When you think of data, you may think of a long list of numbers which represent a measurement. However, this isn't generally the most useful way to look at a set of data. When we look at data, we use data visualizations to help us understand the data more quickly and efficiently. You're probably familiar with at least one type of data visualization, the graph, but we'll explore some more of the variety of ways in which people look at data in this module.
in-context


CANVASES
CanvasOpen
CanvasClose
ActiveCanvas
SetCanvasVisible
CanvasIsVisible
SetCanvasViewport
GetCanvasViewport
Canvas
SetCanvasOffset
GetCanvasOffset
GetCanvasSize
ClearCanvas
SetCanvasAlpha
CanvasAlpha
CopyCanvas
CloneCanvas
SetCanvasZ
CanvasZ
CanvasClip
SetCanvasBlendMode
CanvasBlendMode
SetCanvasColorMod
CanvasColorMod