Friday, June 30, 2017

Count number of lines for each PDF in a folder

This is just a note about a script which may be useful to you. This one calculates the number of lines per PDF and prints the final count.

import sys

import fnmatch
import os

matches = []
for root, dirnames, filenames in os.walk(sys.argv[1]):
   for filename in fnmatch.filter(filenames, '*.pdf'):
       matches.append(os.path.join(root, filename))

count = 0
for mat in matches:
   if not mat.lower().endswith("pdf"): continue
   cmd = "pdftk " + mat +  " dump_data | grep NumberOfPages > pn.log"
   os.system(cmd)
   try:
     f = open("pn.log")
     l = f.read().strip().split(":")[1].strip()
     f.close()
     print(mat + "," + l)
     count = int(l) + count
   except:
     continue

print(count)


Have a great weekend ! :)

Tuesday, June 06, 2017

On "The Computer's Common Sense"

Background
On the surface of it, this is a followup of blog "The Computer's Common Sense" [read here: https://rulasense.wordpress.com/2017/05/] by my friend AKD (https://twitter.com/alok_damle) who is passionate about building a new kind of intelligent system. This is also about my understanding of the machine learning tools that I have used in my work at VLife (which is now Novalead Pharma). These are the thoughts that are coming from a beginner to intermediate person with ML background, so this is more of a learning via conversation exercise for me, and more philosophically skewed rather than looking technically deep.

Artificial Intelligence vs Human Intelligence (commonly called common sense)
AKD starts of his blog with a title that makes you think a bit. It seems to equate Human Intelligence [W1] with common sense [W2]. To me however, common sense (of how uncommon it is), is one part of human intelligence, it is not the only form of intelligence that humans have. Further common sense, as the name suggests, is not something specific to an individual, but has evolved over time from a group of individuals, representing common knowledge - or to put it in other words it is "ensemble intelligence" rather than something that represents and individual humans. Thus, I feel that human intelligence is a combination of many factors - only one of which is common sense. The decisions that humans take is a cumulative effect of various factors.

RULA – Read Understand Learn Apply
If we get past that oversight, some of things being to make sense to me. The example of screw driver (https://rulasense.wordpress.com/2017/05/17/artificial-intelligence-vs-common-sense/) kind of makes sense for the current state of art on AI. It is mostly possible that no AI will suggest using your finger nails instead of screwdriver! *. But the reason for this is probably to do with other environmental factors that the human is in. The human brain, more often than not tries to correlate the present situation with the past situations it has encountered (when in isolation), or it tries to correlate with what others have discovered when being in similar situation (the common sense part). In isolation, a human brain probably works by "read (or observe) - understand - learn and apply" cycle, but that may not be the case always. The second term "understand" is kind of misnomer here - because one can short this with "read (or observe) - learn and apply", with "understanding" coming at a later stage - probably a far later stage. A lot of what we humans do probably translates to "read (or observe) - learn - apply". For instance, take any kid, he observers his parents, tries to learn from them, and then do similar things. He doesn't understand what he does till he grows up. Thus I feel, "understanding" comes after a series of reinforcement learning and application to what was observed. Evidently a lot of AI at the moment is focused on "read (or observer) - learn - apply" cycle and probably never come to the point of "understanding". Deep learning, may however be the ones that actually bring understanding to this process [W3].

Machine Learning vs Human Learning
That brings me to the next part of the blog, which is kind of generically titled. I think the core theme of this section is to bring home a point that most of the AI today is basically data driven. Human learning however can happen at a much superior pace and doesn't need as much data. This is quite true. But I think that this is rather possible because not only the human brain is one, but our brains are connected as a lot with other intelligent beings - and this collective brain power, which is essentially to a large extent what "common sense" encompasses - influences our individual brain learning capabilities. The "collective brain power" is not necessarily of humans, it would be be from any other form of intelligence behaviour - other animals, or even insects. Human brain is capable of capturing and basing its learning on information acquired by other intelligence forms. A counter point to the kids example above, is how often we find that the little ones think differently to what is previously conceived. That, I feel is because the kid's brain is kind of "disconnected" from the "collective brain power", that prompts the brain to potentially discover new ways to solve a problem - which an adult's brain just defaults to "common sense" part.

AI at the moment is limited to what humans feed it with. It doesn't have unrestricted access to the environment outside - as we humans have. Whether that is a shortcoming of current AI or if the AI as is implemented today needs fundamental rethink is what is yet to be seen. AKD thinks that there is an alternate way that is not yet explored. I await to see what is that.


NOTES:
* I am not sure how IBM Watson[R1] will respond - because Watson is a totally different take and at edge of AI research today, and that it could beat humans in the game of Jeopardy! is anything but amazing.

References:
R1) IBM Watson: https://www.ibm.com/watson/
R2) L. Deng, G. Tur, X. He, and D. Hakkani-Tur. "Use of Kernel Deep Convex Networks and End-To-End Learning for Spoken Language Understanding," Proc. IEEE Workshop on Spoken Language Technologies, 2012

Wikipedia:
W1) Human Intelligence https://en.wikipedia.org/wiki/Human_intelligence
W2) Common Sense https://en.wikipedia.org/wiki/Common_sense
W3) IBM Watson https://en.wikipedia.org/wiki/Watson_(computer)

Friday, June 02, 2017

Serval Project: Carrier independent network

Almost 5 years back, while putting in an my idea of building a mobile experience for myself, I had suggested a carrier independent network is what I want - something what will not only distribute the need to create infrastructure but also free us from lousy carrier plans and create a world where communication is free between humans where ever they are. [Ref: http://tovganesh.blogspot.in/2012/01/kosh-building-mobile-user-experience.html]. Obviously carrier based / satellite systems are necessary for emergency situations - but our reliance on them could definitely be minimised.

So when I saw the Serval Project (http://www.servalproject.org/), I was pleasantly surprised that they have exactly the same goal. More over, instead of building a whole new OS as I earlier proposed they are going for a more practical solution of putting it in an Android app. This is a big shout out to you guys developing the Serval Project. It is like a moment when you feel that you are not alone in the thoughts you have about how to make things different in this world. I have just installed the app on my secondary Android device and tested it with a friend. Though the interface is quite primitive at this stage, and the call quality not upto mark - it works. It is experimental and yes, it will improve.

After digging a bit into history of Serval Project (http://developer.servalproject.org/dokuwiki/doku.php?id=content:about), I discovered that it was proposed almost 2 years before I had written the above mentioned article and an early system was used for emergency response during Haiti Earthquake.

The Serval Project is also opensource (https://github.com/servalproject) and in the coming days I plan to explore this project more in depth to see if I can contribute in some way here.

Meanwhile any one should be able to install the app from Google Play (https://play.google.com/store/apps/details?id=org.servalproject), and be the part of experiment and the quest to build a carrier independent backup network. 

Saturday, April 01, 2017

This is how birds enjoy water ...





This is how much the sunbirds in my garden enjoy even with the little water you share with them this summer. They are pretty cool :)

Musings on Nature around Gandhkosh

Some of shots of nature taken around DSK Gandhkosh, my work home over a period of few months. Hope you like it :)

















Friday, February 24, 2017

A "Generic Component" in Angular 2

I am generally a lazy person. Especially so when it comes to writing some UI code (although I can have endless comments and critiques on someone else's UI and UX ;-)) . I find it repetitive. And any form of repetitive behaviour is ripe for automation. One such activity which I recently encountered in a project I was doing was creating forms - a lot of them - with Angular 2 front end. I remember in good old MS Access days these were just a click away - although I disliked it, this is what I did in my first paying job in summer break of my school.
I am not sure we have something equivalent here - more so when Angular is so rapidly changing and keeps breaking every other month.

However, it is rather easy to write a "generic component" that can be simply configured using a JSON and you can have a new form without writing any of the usual code. This has two main advantages: 1) You have a single place to fix when Angular changes something in its structure 2) You have a super reusable form engine which can be configured on the fly, allowing you to do cool things like storing form info in a backend service, and automatically update the Angular 2 app on the fly.

To start off, you will need to define a JSON which can be used to construct the UI on the fly.

this.componentJSON = {};
this.componentJSON['title'] = "Trials";

this.componentJSON['formItems'] = [
 { "type": "text", "id": "trial", "name": "Trial Name", "description": "Name of trial", "theValue": "", "param_name": "trial_name" },
 { "type": "text", "id": "sponsorer", "name": "Sponsorer", "description": "Sponsorer of the trial", "theValue": "", "param_name": "sponsorer_name" },
 { "type": "button", "id": "submit", "name": "Submit", "description": "Submit the form", "api_call": this.createTrial },
];


The above JSON is intended to create a simple form with a title, two text fields and a button. The api_call parameter of the button is a Service object used to make an API call.  This JSON should be used in any parent component that intends to use this component, typically being initialised in ngOnInit() method.

Next we define generic.component.ts and generic.component.html as follows

import { Component, OnInit, Input } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';

@Component({
   moduleId: module.id,
   selector: 'generic-cmp',
   templateUrl: 'generic.component.html'
})
export class GenericComponent implements OnInit {

   @Input()
   componentJSON: any;

   constructor() { }

   ngOnInit() {
   }

   callAPI(item: any) {
     item.api_call.api_call(this.processInput(this.componentJSON)).subscribe((res:any) => {      
if (res.status == 0) {
        alert(res.result.message);  
} else {
        alert(res.error.error_message);  
}
     });
   }

   processInput(componentJSON: any) {
     var formItems = componentJSON['formItems'];

     var params: any;
     params = {};
     for(var frmItm in formItems) {
if (formItems[frmItm].type != 'button') {
        params[formItems[frmItm].param_name] = formItems[frmItm].theValue;
}
     }

     return params;
   }
}













The trick as always is to generalise the JSON and then the generic component generator above to take care of different input forms as well as adding validations. The callAPI function above for instance, basically generalises an API call, where as the processInput method creates the parameter payload for API call from the JSON we created earlier. Advantage again being that simply changing the JSON pretty much re-creates the whole of the HTML. Creating a different form just requires one to define a new JSON.

Since this component needs to be used in multiple places it would be wise to declare the directives associated with this component in a shared.module.ts file:

import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';

import { NameListService } from './name-list/index';
import { GenericComponent } from './generic-component/generic.component';

@NgModule({
    imports: [CommonModule, RouterModule, FormsModule],
    declarations: [GenericComponent],
    exports: [CommonModule, FormsModule, RouterModule, BrowserModule, GenericComponent],    
})

export class SharedModule {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: SharedModule,
            providers: [NameListService]
        };
    }
}


Now a third component can embed this reusable, configurable component as using:



Thats it! You should have a fairly reusable forms module, that you can fully configure using the JSON, without the need to keep writing the HTML and related Component code every time. 

A similar pattern may also be used for creating a generic service call. This is again useful as you code can remain independent of the changes that may occur in basic underlying syntax of say actually calling the HTTP post method. 

Wednesday, January 04, 2017

My tech wish list - 2017

1. MacBook with inbuilt cellular connectivity
2. iPhone with no ports - not even lightning - with wireless charging. For a truly courageous furture.
3. If I can just use my phone for every thing - where is that elusive Surface Phone ?
4. On demand apps on iOS - so that I can save on my precious local storage
5. Driver less cars - where are they ?
6. Super personalised medicines
7. AI assistant for myself - without a cloud connected device
8. Battery that lasts for 1 month on 15 min charge and doesn't explode. 

Saturday, October 15, 2016

A memory corruption bug as result of 'single character'

It has been a quite a few months since I saw or have written some serious algorithmic code involving C++ (read computing surfaces or doing numerical computation). So when a weird bug was reported for a program I work with, I though it must be fun. The case was for a particular feature in the program that would plot a surface based on some input parameters. The bug was strange because it made the program crash on Windows but on Linux it plotted the surface correctly.

Good then, let us fire gdb and figure out where it was faulting. But for some reason, on the build system I was using for Windows, I couldn't get gdb to work properly. So was left with old way: read the code and put a lot of printf(). Now since this was Windows, printf() wouldn't work either! The program however had a logging API, that would log text to a window. The problem however was that there was no text in the window (or the window was not refreshed) just before the program used to crash. So the next technique was to use the logging and commenting one line at a time, with a premature return from the affected function, which is usually very tricky to do when there are nested loops. And this was exactly the case here. Finally, the real culprit was one line that read:

if (k+l < numberOfXPoints) {
 ....
 x[i][j][k+l] = ...
 ..
}

There you have it. The code ought to be:

if (k+l < numberOfZPoints) {
 ....
 x[i][j][k+l] = ...
 ..
}

Apparently this error was never observed, and looking back at the history of the source code, I found that it was this way ever since it was written, a couple of years ago! This error didn't probably produce any visible output errors and apparently went past all the test cases as well, because for none of those, the points along z-direction exceeded the points along x-direction.

Two things to learn:
1) Never name two variables such that they differ in only one character. If you indeed need to then ideally have the differing character towards the beginning of the word as in the case above a better way to name would have been using: xPts and yPts.
2) If an error is occurring on one platform but not on another, it is most likely a memory corruption issue. Hunt down all the code dealing with arrays. 


Thursday, May 12, 2016

Experiments with super capacitors and solar panel



Towards the end of 2012, I started experimenting with powering devices directly using solar panel and an pretty expensive super capacitor. For this I bought a couple of solar calculators from a nearby mall, disassembled the tiny solar panels and tried to run a small mp3 player using the same. The project kind of got shelved, towards the beginning of 2013 due to loss of my mother.

Later on in 2014, I got some pretty inexpensive but good quality super capacitors from eBay. And then repeated the experiments. I tried two things:
1) Powering the calculator fully on solar and super capacitor
2) Powering an MP3 player using a super capacitor and a slightly larger solar panel (again ripped off from a solar power bank)




While the fully solar calculator (supported by the super capacitor) works wonderfully well (even today), the MP3 did work pretty well too. The only issue with the MP3 player being that the 1F super capacitor I had only lasted for about a minute if I got it away from direct sun light. The calculator on the other hand, requiring pretty low power didn't have issue with even ambient room light.

I believe super capacitors combined with solar panels have interesting applications. Especially in wearable world. It is only a matter of time that these things become common place.

Friday, April 01, 2016

A Thousand Times


I must have talked a thousand times .. to myself
Where are you ? Where you?

I must have walked a thousand times
To see you. Where you ?

I must have heard a thousand times
About you. Where you?

I must have walked a thousand miles
Still here 
Wondering what am I doing still, again and again and again ..


                               


Saturday, February 13, 2016

Printing on a white label BLE thermal printer from iOS - a quick story

Over at OneGreenDiary.com, we are building tools to help small merchants better connect with their customers. Check OneGreenDiary.com to see what we do, and do not forget to watch that video, we are sure you would love it :-)

While one of the core principles at OneGreenDiary is to be as paper less as possible, there are still places where a printed paper bill may be required. We avoided print support for our merchant apps, till one of our early adopters specifically asked for it. Since we are kind of cash strapped, and can not afford to spend on a damn printer that is iOS certified, we went over to alibaba.com and ordered this cheap Bluetooth enabled thermal printer that claimed to work with iOS : http://tousei.en.alibaba.com/product/60371489659-802143527/TS_M230_mini_bluetooth_portable_handheld_receipt_bill_printer_for_android_ios_mobile_58mm.html


Great. After the printer arrived, we though that it would magically connect to out iOS device and we did start printing instantly. Bummer. Ok, how about Android ? No luck. Apparently neither iOS nor Android provide native support for BLE printers. I tried to install the outdated Windows driver, and Linux cups drivers with no luck. Not even able to print on desktop. 

But then, Abhay C, a wanderer with us, found an iOS app called printer-x, that was a demo app to print on bluetooth enabled thermal printers. He printed this:  "hello, world!"

At this point we knew, it could be done. But how? All communications with the vendor didn't go anywhere. They send some sample iOS (Objective C) code, and some Android code, both of which didn't compile, and neither we could understand what was going on in the code. There were a few comments in Chinese that tried to be helpful. Chinese, not Swift. The programmers manual that came with printer reminded me of good old DOS assembly days. There was something, but didn't know where to start.

Next we tried to venture into programming our own BLE layer for printer communication. Instead of using the CoreBluetooth library we zeroed in on using BluetoothKit, which is Swift wrapper over CoreBluetooth library (https://github.com/rasmusth/BluetoothKit). So basically it is this: BLE frameworks try to give you two interfaces: Peripherals and Central. Peripheral refers to a device which can be discovered, asked for data, or can receive data. Central on the other hand scans for Peripherals, discovers characteristics offered by Peripheral, receive / send data to the Peripheral. One of the important thing to enable discovery is the UUID of the Bluetooth device, this can be easily obtained by using a discovery code, or a number of BLE query apps available on the App store/ Play store. I used the LightBlue app from the App store for this purpose. Once this device was discovered, we needed to connect to the device. The BluetoothKit provides a elegant interface to connect. But the issue started after this: apparently BluetoothKit's connect call back returns an instance of BKRemotePeripheral class, and this class exposes API to only receive data, not send! Apparently the class was more designed for bluetooth sensors, that only transmit data, not receive anything. Digging into the BKRemotePeripheral class, I found out a way to expose the embedded CBPeripheral object along with capturing CBCharasteristic objects. These are the objects of CoreBluetooth iOS library that allow lower level controls.

Next is when the DOS assembly like programmer's manual, which came with the printer, came up for help. After this I could easily figure out the code to issue a line feed to the printer device:

let lineFeed = self.hexToNSData("0A")
let printer = self.connectedDevice!.getPeripheral()!
printer.writeValue(lineFeed, forCharacteristic: self.connectedDevice!.getCharacteristic()!, type: CBCharacteristicWriteType.WithResponse)
At this point, I knew, things were pretty much in control. The above code basically writes the hex code "0A" to the discovered characteristic. This initiates a line feed operation on the printer. Once this is done, it was a wow moment to print this:


and then this:

Since all of this code (written in Swift) was majorly based on BluetoothKit, we felt it was best to open up this part of the code, which is now hosted on GitHub: https://github.com/tovganesh/bleprinter-ios

Hope this is of some help, especially if you are trying to programatically access these kind of printers with iOS.

Note: Before you ask, I am still connected with VLife for all official (and practical) purposes. Once an officer at immigration and citizenship department in Oz told me, it is always good to be in love with two countries, you are contributing to both with your heart. Fits well here. 

Saturday, January 30, 2016

You don't need a desktop on your Smartphone


There are two companies that are trying to position their mobile offering with a standout feature. Microsoft's continuum and Canonical's convergence mean the same thing to an external user although the way they are implemented is a lot different. Both of these implementation, however fail miserably in one important department: mobility. And that is precisely the reason I use a smartphone to do lot of my tasks on the go.

Both continuum and convergence require extra hardware to get it working: A dock, keyboard, a mouse, and an external screen. All of which completely defeats the purpose of the whole thing, atleast for me. There is another bigger issue. When you try to shove in the desktop to a form factor like a smartphone, you basically stop looking at ways to use different UI paradigm and design to improve productivity on small screens, with the pre conceived notion than only a bigger screen is needed for actual productivity. One of the prime examples of this issue is how poorly the Microsoft Excel for iOS is designed as compared to how well Apple Numbers is designed. 



While the default keypad for entering numbers and dates (two most frequent entered entities for a spreadsheet) in case of Apple Numbers is very easy and fast to use adapted keypad, in case of Mocrosoft Excel it is pretty standard looking and difficult to use keypad for the context: 


Canonical's approach is no different. In that for productivity suits like LibereOffice, there is literally no thought on how to design UI for the small form factor. Rather, the argument is to simply connect an external monitor to get a full Ubuntu desktop. Cool for geekiness, zero for usability.

In the end I see both Continuum and Convergence as defensive response to ultimate failure to innovate on the small screen. The Apples approach to bridging the gap, dubbed Continuity, though useful for a limited scenarios, feels more like a proof-of-concept rather than something that I can truly use for my workflows. All this workarounds until of course we have hardware technologies like the bendable or foldable displays become a real consumer reality. 





Monday, November 23, 2015

Live Molecule search: a quick hack using JSME, Cactus, AngularJS and BootStrap

For an internal project, I needed a web control that will display the structure of the molecule as I type in the name (or SMILES, CAS number, IUPAC name or a host of other ways you can textually describe a molecule in one line). Now this is not really easy, but thanks to the some open APIs provided by the CADD group at NIH/NCI (http://cactus.nci.nih.gov), it was really easy to get this done.

Here is a quick overview of the hack I wrote. The code for the same is available on GitHub (https://github.com/tovganesh/mol-auto-view.js)

The final control. You give a molecule description, the molecule appears in draw area, click "Save to list" and it gets saved to a list that is depicted on the right hand side.


The Cactus (http://cactus.nci.nih.gov/chemical/structure)

The molecule description can be given in various ways, and it usually a very tiresome task to think through and write interpreters. One can of course use tools like Open Babel or CDK, but a more cleaner interface is a web service offered by NCI, called the Cactus. A simple API call as follows,
gives you a mol file that can be viewed:

http://cactus.nci.nih.gov/chemical/structure/[Molecule Description]/pdf


JSME (http://peter-ertl.com/jsme/)

Next to view this structure, I use the simple but powerful 2D molecule drawing tool by Peter Ertl and Bruno Bienfait (http://peter-ertl.com/jsme/)

I, particularly use the following API:

jsmeApplet.reset();
jsmeApplet.readMolFile(dataFromCactusAPICall);


The above call is the clear the drawing area, and read in the new molecule file obtained from call to the Cactus API.

Next, I need to get the molecule file data from JSME and well as a graphics representation to show in a list. This is does using the following API call:

molFile: jsmeApplet.molFile(),
molImage: btoa(jsmeApplet.getMolecularAreaGraphicsString())


The first call is for getting the molecule data, as a mol file. The second call is to get the graphics of the molecule as a SVG data, that is then encoded to base64.

Putting it all together: Angular JS and Bootstrap

Putting it all together required using Angular JS and some basic Bootstrap. The following is used for the text field that takes the molecule description:



The above code is used to fetch the mol data from giving a call to the cactus API, as you type the molecule text. The model change even is delayed by 750ms, so that the API call is only fired, when the user pauses for some time. 

Thats it! I hope you find it useful. To see the full code see Github: https://github.com/tovganesh/mol-auto-view.js



Monday, November 02, 2015

Change in MeTA Studio licensing

Starting today, the MeTA Studio code base will be re-licensed under a more permissive MIT license (https://opensource.org/licenses/MIT).

On a side note, if you are not already aware, the new active home for MeTA Studio is GitHub (https://github.com/tovganesh/metastudio/)

Wednesday, October 21, 2015

ViTAL Lite : An app for computational genotoxicity alerts

Computational toxicity assessment is a mandatory regulatory requirement for pharma industry. A number of companies provide these services to pharma companies. ViTAL (http://www.vlifesciences.com/products/ViTAL/Product_ViTAL.php) is one of the industries most comprehensive, regulatory compliant reporting service offered by VLife Sciences (a division of Novalead Pharma Pvt. Ltd.).

If however, you are looking for a quick way to check computational toxicity alerts for molecules, VLife Sciences has introduced an Android app for the same. Check out the app at: https://play.google.com/store/apps/details?id=com.vlife.vitalite

PS: The ViTAL service, provides a more comprehensive regulatory compliant report (literature survey, multiple updated toxicity models etc.), where as the ViTAL Lite app provides a simple alert indicating probability of the molecule being genotoxic and/or carcinogenic.

PPS: I work for VLife Science.

Sunday, October 18, 2015

Running mobihf on the iPhone

mobihf (https://sites.google.com/site/tovganesh/s60) is a code that I wrote almost a decade ago on my first phone: the Nokia 6600. mobihf was meant to be an educational tool on how to write a basic Hartree-Fock Quantum Chemistry code from scratch, and to me it was a way to experiment on how much can I push the mobile device to do scientific number crunching. At that time the processing power of my mobile was just about 100MHz with just about 10MB of RAM! And now I have this two year old iPhone 5s that has a 1.3GHz 64 bit processor, with about 1GB of RAM.

To test out how things have panned out for my purely Python mobihf (not the C++ integral code that I wrote later), I tried a number of Python interpreters available on the Apple App store.  While Python for iOS (https://itunes.apple.com/us/app/python-2.7-for-ios/id485729872?mt=8) seemed like a good choice, its editor was never able to even load the mobihf script to do anything meaningful. A mail to the developer did not get me any response (as of this writing).

Next up was pythoni (https://itunes.apple.com/in/app/pythoni-run-code-autocomplete/id493505744?mt=8). This is surprisingly well written app with custom keyboard shortcuts and well made editor for editing Python scripts. It is worth buying the pro features in this app if you do a lot of Python programming on the move. So, finally I was able to run the pure Python mobihf code (available from GitHub: https://github.com/tovganesh/myrepo/blob/master/mobihf.py). This code is heavy on numeric computations (evaluations of exponential functions, matrix and vector algebra etc.). Without going into the details of what the code does, I typically run two test cases to see how things are going. These are for two very simple molecules: H2 (hydrogen molecule) and H2O (water molecule) at a basis level called STO-3G. All very basic to the one who knows Quantum Chemistry, and pretty much a jargon to the rest ;-) Since I am using iOS9, I decided to run the job in two modes: once with battery saver on and another without.


As can be observed above, even with battery saver on, there is 50 to 65 times improvements in the timings over the same pure Python. And, to top it the timings also handsomely beat the C++ compiled code on the old phone.



With the battery saver turned off, the performance improves as expected. What is surprising however is that in comparison to when the battery saver is on, the performance improvement is about 60%. That is quite a hit to keep the phone going for longer. I wish we have some radical improvements in the battery technology so that we can keep enjoying our devices at full speed.

The next app was Sketch Python (https://itunes.apple.com/in/app/sketch-python/id984990674?mt=8). There are a number of different Python implementations and each can give you a different performance numbers. So far I have found Sketch Python to be the fastest.

With the battery saver on, Sketch Python performs almost as fast as pythoni with battery saver off. That says a lot about the performance of Sketch Python interpreter, especially in handling Python code with heavy numeric computation.


The performance of Sketch Python to run mobihf increases substantially when battery saver is off, and is probably the best timing that I can get on the A7 processor of iPhone 5s. If you do the math, this is 140-166 times faster than the pure Python code that ran on my Nokia 6600 a decade ago. In comparison to the C++ (native code) running on Nokia 6600, the gains are an order of magnitude times less, but still impressive. I am sure if I port this code over to native, we can do pretty complicated Quantum chemical calculations on the phone. The newer A9 processor in iPhone 6s or the Qualcomm processors (8-core 810 or higher), would be interesting processors to see the current state. But I can say that these mobile processors have reached the performance levels of the most desktop processors for all practical purposes. And this is exactly that I had in mind when I took a look at the ability to run scientific codes on mobile processors (https://sites.google.com/site/tovganesh/s60).

On a different note, the ARM architecture also makes an interesting case for computational codes because of the low power requirement, a topic I briefly touched, but now studied much deeper by Kristopher et.al. (http://pubs.acs.org/doi/abs/10.1021/acs.jctc.5b00713). Alistair Rendell, my postdoc guide, is a co-author in this paper, so it must be real good :)

Note: The experiments above were run 5 times, and the lowest time was taken.
PS: This post has been since mentioned on MacInChem.org (http://www.macinchem.org/blog/files/0c7f90a37910d2ed90402dcddb6cf4e2-1814.php)



Wednesday, August 19, 2015

ambado.js - releasing an experimental, lighweight and fast web app framework

I am a releasing a new open source project called ambado.js, which aims to build a lightweight and fast web app framework. It is experimental, so I will try a lot of ideas I have in mind, and is not really useful for production releases at the moment.

I have been building a number of webapps for our company (www.vlifesciences.com) for consolidating various platforms and services that we offer (drug discovery, toxicity etc.). One of the issues I have been observed during these developments was that of the load time for these apps, which are a lot dependent on loading of the initial scripts, html, css and images. There is no particular emphasis on caching in most frameworks, that would have improved quite a bit of load time and ultimately user experience. Recently though, I found basket.js (http://addyosmani.github.io/basket.js/), which is a wonderful library that does caching. Although, basket.js does a good job, I wanted to extend the idea to a framework that uses the concept of caching itself from ground up, rather than attaching the piece of code externally.

So two days ago, I started putting some basic code together, and now I feel it is kind of usable for the world to see and progress further. The code is hosted on GitHub, and is called ambado.js (https://github.com/tovganesh/ambado.js). ambado.js uses lazy but aggressive loading of resources, currently using the basket.js library. Additionally, it provides a simple framework to build very simplistic UI.

P.S:
Ambado, by the way, is Konkani for Indian Hog Plum (https://www.flickr.com/photos/dinesh_valke/3393914087). We also use it to make pickles, which I love taking with plain rice :-) Although, I only recently tasted it after almost a decade!

PPS:
ambado.js is at a very early stage, things are going to break!

Sunday, July 19, 2015

And so I bought a flat ...

With the kind of crazy prices for property going around in the city I stay (Pune), I never thought I would buy a House. But I did end up buying a small flat. And it was an experience.

My mother always wanted me to buy a flat. I never liked the idea. For all my life, I have lived in a row house, and our house back home in Kerala is a small garden plot with a house. Moving to vertical arrangement, with no garden, no greenery, probably no birds to wake me up in the morning (I almost never use an alarm, it doesn't work for me) made me dislike the whole idea of buying a flat. I always used to argue with my mother, when she used to keep suggesting me places to look for. Two years ago, that stopped. She left us forever suddenly. I was completely lost and had no idea where my life was heading (I am still trying to figure out and learning every moment).

Somehow, last December, I had this thought of buying a small flat. A 1BHK one. So I started off the usual way I start finding anything: online. I registered on magicbricks.com. It was a disaster. I was literately spammed with emails and phone calls. I somehow managed to close my account with them. But in-between my e-mail apparently got leaked to other two sites and they apparently started spamming me. Thankfully, the GMail spam filters saved me from further point less e-mails. I must say that I didn't know about Housing.com at that point, probably my experience would have been better.

In the mean time I also registered on the DSK website saying I was looking for a 1BHK flat in or near Baner (as this is near to the place I currently work). I had known DSK as a builder largely because of the wonderful 'DSK Gappa' program they run on the Pune local Radio, where the main guy DS Kulkarni carries out a conversational program. The beauty of the program is that they never advertise that they are a great builder and they are building a new site, go look and buy. DS Kulkarni instead talks on varied subjects, and buying a house is one of the main subjects. In any case, with the kind of spamming I received from all the online sites, I was not really expecting anything from DSK. But suddenly out of blue, one Saturday I got a call from DSK office saying they have few flats for ready possession at DSK Gandhkosh project, which is walking distance from my Office. I indicated to them that I would like to visit the site. And did so the coming Monday. I was not expecting that I would like a flat at 10th floor, when for all my life I have lived on ground zero, with a garden besides. But as soon as I entered the flat, it reminded me of the small apartment that I had rented when I lived in Canberra, only a lot better, with a nice airy terrace. At the very moment I had decided that I would be buying this very unit and not the others he was going to show me. It was B1001. Perfect binary ;-)

Well I was not quite sure of price to what I was getting, so I negotiated a bit and they gave me some discount. Then I came back two days later with few of my office mates to just understand their perspective, on if I am doing the right thing buying this flat. They too liked the flat, and suggested that I buy it even if I may not like to stay always here! Well, maybe, I thought.

Next, did my father like it? So the next weekend we visited the site together. To my surprise, my father too liked the place. And so we decided to book the flat just few days before my 35th birthday. I have a habit of giving gifts to myself, since no one gifts me ;-)

Interactions I had with the builder (DSK), were one of the most pleasant one. Once I had decided to buy the flat, the obvious next question was finances. The DSK guys wanted me to give them an advance of 5L INR for booking. Which obviously was not immediately available in my bank account. So I gave a part payment and my Father said he will give me some from his savings, which would make up the amount. The next thing was the getting a loan. I had never taken a loan before and had absolutely no idea if anyone would ever give me a loan! DSK guys indicated to me that they have some special scheme running with HDFC that would get me a loan at 9.9% interest (at that time the market rate was 10.10%). Since I didn't do much survey, I agreed to meet the sales people from HDFC loan department.

From here, the interaction with HDFC has been quite whirlwind. At first the interaction was quite straightforward and appeared simple. But they kept demanding documents after documents. At one stage it was made to believe that it was compulsory to take a insurance for the loan, and was given only one option. Since the premium was too high, I was in two minds if I should at all go ahead with the purchase of the flat. Although my close friend, father and colleagues from office suggested me to look at alternatives. At each point I felt that there was a lot of communication issue with the people interacting with me at HDFC. In any case the loan got approved.

In the meantime, I signed the agreement with DSK and the deed was registered at the registrar office. The builder arranged for appropriate transport to the office and needed appointments with officials there. It went reasonably smooth.

After this, the agreement papers were collected by the HDFC people, and the loan got cleared for disbursement. Around this time I got a call from some other sales guy from HDFC Life informing me about an alternative insurance plan for loan, I quizzed him on why was this not indicated to me previously, and he excused it indicating earlier conversation as an oversight by the previous guy who contacted me. It was indicated to me that this plan would cover life, disability, fire, theft, natural disaster and a host of other things, moreover it would link directly with my loan, so I would not need additional documentation. I though this was a decent plan, so I asked the relevant person to go ahead. So, imagine my shock when on the loan disbursement day, the HDFC guy tells me that the insurance I opted for only covers life and not any other things! This is where I felt totally bad about the way various people at HDFC were communicating with me. I literally fumed at the guy who was handling my papers. But I realised that there was no point bashing this guy, probably I should have been careful, should have enquired more, or should have chosen a different loan provider all together.

In any case, the loan got disbursed, and I gave some pre-EMI cheque (I later came to realise that I had not signed the cheque!) and here came a bummer: I was now told by the HDFC guy that I have to do property registration with the registrar office for the loan mortgage.  What? I have to again go to the registrar office? Fortunately, DSK people helped here to do this thing for me for a little fee. Sigh!

After all this I gave the disbursement cheque to DSK, and on the same day they handed me the keys to my flat. Along with that they gave me a host of starter kits, a set of books and to top all this they gave me a cheque of about 2800 INR. What was that cheque for? Apparently the DSK guys had deposited my advance amount and the own contribution that I did towards the flat in fixed deposits and the cheque was the interest (- TDS) that DSK was giving me back! This was sweet, considering all the pain I had got through. I felt so good about DSK, in complete contradiction to my feeling towards HDFC.

So apparently I now have a flat, albeit small. After this, I and my Father moved in to this flat. There were a lot of small maintenance issues at the flat, which have been or are being handled by DSK. This month, DSK handed over the operations to a provisional society committee, so technically now DSK is not responsible for any further work, but indicated that they are ready to help in any case.

After the first week of stay, my Father didn't much like the surroundings as the place is quite separated out and is still under development. So now, I shuffle between two homes. Workdays at the new flat, and on weekends to my old sweet home.

There are a few things I like about this new place. Its airy and very quite at the same time. At times it can be windy but it is still pleasant. The second one is the solar water heating system, which I very much wanted in my old house, but never managed to get it done. There are a few things I miss: no personal garden, the common garden however is nice. No malls or even shops near by. I have to walk about 1.5 km to get stuff.

Some photos

(NOTE: The photos below are not high res, they are reduced quality images, if you want to see some of them in full res, visit my Flickr photo stream)

A panoramic view of my flat @ DSK Gandhkosh. Fairly well constructed. 
If you come out in the morning, you will find plenty of interesting birds around DSK Gandhkosh.
Night view of Baner from my bed room window. You can keep staring for long.

The first morning I woke up, nature had a pleasant surprise for me. It was a double rainbow :)

The first morning I woke up, nature had a pleasant surprise for me. It was a double rainbow :)
Another night time view of Baner from my terrace.
A view of the small flower garden at the entrance of Gandhkosh.

Few flowers!

A view from outside of DSK Gandhkosh.


Startup or buy house?

Before I bought this flat, I was in a dilemma, of whether I should put all the money I have in my savings for a startup or buying a house. Eventually something prompted me to buy a flat. Don't know what, but it just happened. I was already working with a very good friend of mine towards forming a small entity to try out things we have been discussing over few months. And almost immediately after I signed my agreement for purchase of flat another friend of mine came up with an idea which I couldn't resist to join in. This friend later told me that even if now I am kind of cash strapped, it was a good decision to buy the flat. I hope so, that is the case :) In the meantime I keep working on my ideas, and hopefully I am of some use for this society and a wonderful nation that has given me so much.


Reflection on my mother 

I always used to jokingly tell my mother, that I would be retiring at the age of 35. Sometimes, I felt that I was quite serious about it. Unfortunately, my mother didn't stay to see me turn 35. If not so long ago, people bought a house when they retired, I can consider my self retired ;) Its kind of a funny feeling however, since you still have to payback a good amount of loan! So I keep working :)