Thursday, June 21, 2012

Tesseract OCR: Interactive Debugging Continued. Baseline Viewer

Here I'll describe a method of viewing baselines in Tesseract's interactive debug environment.

Those who use Tesseract 3.02 should first read my former post called Tesseract OCR: Setting Up Interactive Debug Environment On Windows and complete all steps from it. However instead of the installation suite mentioned there you would need another which contains updated Tess config files as Tesseract developers had renamed/removed a number of internal debug parameters since version 3.01 used in that tutorial. Download the updated suite at http://www.4shared.com/zip/FnP8RSu0/tess_debug_3_02.html. Version 3.01 users can still use the old installation suite.

So now that you've completed the step 5 from the former tutorial and the debug window has appeared, do the following:
  1. In the main menu choose Modes->Show BL Norm Word. No apparent reaction from the UI should follow. This is normal.
  2. Now click on any word you're interested in. A new window titled BlnWords should appear.
  3. At first sight the BlnWords window is empty. But in fact this is not true. Nothing is visible only because of the quirky scaling logic used by ScrollView. To find something inside the window you need to use window scrollbars to pan and mouse scroll wheel to scale up/down. I suggest the following sequence for initial setting of the view:
    • slowly drag down vertical scrollbar thumb until you see baselines and/or outlines,
    • move horizontal scrollbar thumb approximately to the center,
    • use mouse wheel to scale the window contents properly,
    • you may also resize the window to your taste.
  4. While you click other words in the main window the contents of the BlnWords window updates. You can adjust the view as needed using the methods described above.
What is displayed inside the BlnWords window are so called baseline normalized words. In this type of view words are shown as if their baselines (which can be curved and/or inclined in the source image) get straightened and positioned strictly horizontally. In addition to the baseline the window shows also x-height, ascender and descender lines. See more at Wikipedia: x-height. Using this view you can clearly see if a baseline found by Tesseract is right or wrong: incorrect baselines cause characters to "jump" or "fall."

Baseline finding greatly influences character classification. Various baseline-relative positions of the same character can lead to completely different recognition results. That's why incorrect baselines often serve as sources of errors in Tesseract recognition.

A few examples. Let's take the "conventional" phototest.tif file:
The main debug window should look like this:
All baselines seem to be found perfectly:
For more complex images things go worse. Here I've taken an photographic image of a restaurant receipt. In the image the receipt appears to be inclined and perspectively distorted. The paper is a bit curved, just like it usually happens with receipts. The image is precooked by my image processor (only done binarization and noise cleanup) so that Tesseract is able process it, at some degree of success.
The main debug window already shows several segmentation failures. Some characters are grayed out and some are missing completely:
In BlnWords one can see that many baselines are good but some are determined incorrectly, for instance:
Also there are some epic failures, like these (meaning that characters from adjacent rows get segmented into a single word):
So why would you want to use this debugging method? It can be of use when you're investigating the reasons of some Tesseract failure. Baseline viewer can help you to see that an additional preprocessing is required to cope with the image or a set of images, either programmatic or by means of 3rd party software such as ImageMagick. Passing image block by block (i.e. full or partial pre-segmentation) might also help. Another approach is tweaking internal Tesseract segmentation and baseline finding parameters via config files. Yet another approach is source code changes.
more >>

Monday, March 7, 2011

Visual C++ 2010: Detecting Memory Leaks For Global Variables

This article is a hint for those who feel desperate with finding the origin of a memory leak in their programs. I suppose you've already read the Microsoft's documentation on this topic - Finding Memory Leaks Using the CRT Library - and set up your project to enable leak detection.

The documentation states that if you did everything properly, the Output window should display all the leaked memory blocks along with source file names and line numbers. However sometimes it's not the case and there's nothing shown except a bare memory address and allocation size. And you end up staring at these numbers, puzzling over what you could do wrong with leak detection setup, placing exit()s all over the code and trying to understand logically where those damned leaks could originate from.

Actually this might be not your fault that you don't see line numbers. To be precise, it's not your fault but it's a problem of your project's design. Probably your project uses many global variables which get initialized long before source line number tracking is in effect and thus in the end debug CRT detects leaks but cannot report line numbers. Global variable usage is unavoidable in large and complex projects so we need some method to fix such leaks.

The good news is that such method exists. The bad news is that it involves much manual work. But at least it works.
  • First you'll need to make a whole program run to get the entire memory leak report in the Output window. Copy the memory leak report somewhere, e.g. to a Notepad window, as later you'll need these numbers in curly braces called memory allocation numbers.
  • Open the crt0dat.c file in Visual Studio. I assume that during the Visual C++ installation you had chosen the default folder, so that file should be located in "C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src".
  • Within the crt0dat.c file, search for the following string (no quotes): "__cdecl _initterm_e". Place a breakpoint at the first statement of the _initterm_e() function.
  • Run your program again. The execution stops at your breakpoint. Now go to the Watch window and type "_crtBreakAlloc" (no quotes) in the Name column. In the Value column most probably you'll see -1.
  • Disable the breakpoint in crt0dat.c. You won't need it to be hit again during this program run.
  • Now get back to your Notepad window and copy to the clipboard the first of the memory allocation numbers in curly braces. Go to the Watch window in Visual Studio and in the Value column replace the value shown with the value in the clipboard. Press Enter.
  • Resume the execution by hitting F5 or choosing Continue from the menu. After a while Visual Studio should display a message that reads "<YourProgram> has triggered a breakpoint" and stops at some location within the CRT debug code, most likely in the dbgheap.c file.
  • Now go to the Call Stack window and scan it from the top to the bottom until you find a function that is known to be written by you. Now you can conclude on what can be the reason of the memory leak. It might turn so that at the top or in the middle of the call stack there are gray lines containing only addresses. This means that symbol information is absent for some libraries used in your project. Hit Shift-F11 until you get rid of gray lines before the known functions. Ignore "No source code available" messages if they appear and keep hitting Shift-F11.
  • Once you finished your investigation with one of the leaks, you may continue with another without restarting the program. Just get the next memory allocation number from the previous memory leak report, paste it into the Value column for _crtBreakAlloc in the Watch window and hit F5. Investigate the cause of the leak. Repeat these steps until you examine all leaks you have. This works thanks to that memory leaks reported in the same order as the corresponding memory allocations happen.
Why do we need a breakpoint inside crt0dat.c? Because need to capture a memory allocation event before our main() function starts. Once main() is entered, all global variable initializations already happened and we've lost the chance to track allocation events either by hardcoding allocation numbers (using statements like "_crtBreakAlloc = 1234;") or by editing the _crtBreakAlloc watch value during the debug suspend mode. The _initterm_e() function just seems to be a good choice to place a breakpoint.

It is crucial to run your program every time with the same input conditions so as to memory allocation numbers stay unchanged between runs. Once you fixed a leak, you'll need to repeat the whole process from the start as allocation numbers likely have changed.

Hope this info will help fixing your very own leaks.
more >>

Sunday, February 6, 2011

Tesseract OCR: Setting Up Interactive Debug Environment On Windows

The following are the step-by-step instructions for setting up and running Tesseract’s internal state viewer (called "ScrollView") on Windows.

Although there already exists a dedicated wiki article (and the instructions herein are based upon it), it can cause some confusion for Tesseract newbies and those who don’t feel comfortable with the technology mixture required for the setup.
  1. First off, you need to make sure you have Java Runtime Environment (or simply “Java”) installed. If you haven’t, then go to http://www.java.com/en/download/manual.jsp and download it. Most likely, an offline version for Windows will suit you well. After the download completes, run the downloaded executable, follow several wizard steps and wait until the installation is finished.
  2. Tesseract’s viewer requires a few JAR files which hadn’t been changed for years and are a bit of hassle to get. So I decided to pack them all into a single archived installation suite along with the Tesseract 3.01 executable and other required minimal infrastructure. You can grab it here: http://www.4shared.com/get/Z4gnbJdP/tess_debug.html
  3. Then create some folder say C:\tess_debug and extract into it all the files from the downloaded installation suite preserving the folder structure.
  4. Launch the Windows Command Prompt and change the current directory to your folder by running the command
    cd C:\tess_debug
  5. Now you are ready to launch the Tesseract debug environment. My installation suite contains the test file phototest.tif so the command to display segmentation data for it would be
    tesseract phototest.tif test1 segdemo inter
    Type the above command in the Windows Command Prompt. The viewer window containing letter outlines should appear shortly.
    A few words on the command-line parameters used:
    • test1 indicates the name of the txt file which will be created as a result of Tesseract’s work. It will contain the recognized text.
    • segdemo and inter are config files required to run Tesseract in this kind of debug mode (segmentation debugging); you can see these within installation suite’s folder.
    • To run segmentation debugging with your file, indicate its name instead of phototest.tif. If your file is located outside installation suite’s folder then you’ll need to prefix the filename with the path.
    • The above command runs recognition using the default language file eng.traineddata. To use your own language file, specify it using the -l command-line argument e.g.
      tesseract image.tif test1 -l yourlang segdemo inter
      In order for this command to run successfully, the language file called yourlang.traneddata should be placed into the tessdata subfolder of the installation suite folder.
  6. The above paragraph describes how to debug the segmentation. Nearly the same technique is used to debug the classifier. One thing you need in order to change the debugging mode is to replace in the command line segdemo with matdemo, like this:
    tesseract phototest.tif test1 matdemo inter
    NOTE: The matdemo config file can also be found in the installation suite folder.
This is all that can be said about installation of and launching the Tesseract viewer. For information on how to use Tesseract viewer’s user interface please refer to http://code.google.com/p/tesseract-ocr/wiki/ViewerDebugging
more >>

Monday, January 24, 2011

Yii: Getting to Understand Hierarchical RBAC Scheme

Yii is a very powerful PHP framework, and among other PHP frameworks it is distinguished by its great object-oriented design, MVC support, speed, flexibility and many other virtues. Recently I had some experience with the PRADO framework and chose Yii to build my image processing web application demo. It took some time for my app to stay in my home server sandbox and now it's matured enough to be revealed to public. And at this point I came close to setting up my app's security.

Yii is also known for its comprehensive documentation and well-written tutorials. Authentication and Authorization is a good tutorial too. Among other topics, it describes basic aspects of Yii's RBAC implementation. That's what I needed to understand in order to start building my own primitive authorization system. But however hard I read the tutorial, I couldn't understand how exactly the hierarchy works. I found how to define authorization hierarchy, how business rules are evaluated, how to configure authManager, but almost nothing about how I should build my hierarchy, in what sequence its nodes are checked, when the checking process stops and what would be the checking result.

There was no other way for me but to dig into Yii's code and I would like to present my findings in this post. I have to mention that digging in Yii's code is not difficult at all, it's well-structured and everyone can do it, but the following info can save you a bit of time when you're a Yii newbie.

I must say it would be much easier for you to understand the article if you got familiar with the above-mentioned tutorial especially with the topics starting from Role-Based Access Control.

Let's consider the hierarchy example from the tutorial (this example illustrates how security can be built for some blog system):


$auth=Yii::app()->authManager;
 
$auth->createOperation('createPost','create a post');
$auth->createOperation('readPost','read a post');
$auth->createOperation('updatePost','update a post');
$auth->createOperation('deletePost','delete a post');
 
$bizRule='return Yii::app()->user->id==$params["post"]->authID;';
$task=$auth->createTask('updateOwnPost','update a post by author himself',$bizRule);
$task->addChild('updatePost');
 
$role=$auth->createRole('reader');
$role->addChild('readPost');
 
$role=$auth->createRole('author');
$role->addChild('reader');
$role->addChild('createPost');
$role->addChild('updateOwnPost');
 
$role=$auth->createRole('editor');
$role->addChild('reader');
$role->addChild('updatePost');
 
$role=$auth->createRole('admin');
$role->addChild('editor');
$role->addChild('author');
$role->addChild('deletePost');

First of all I'd like to convert this to a more human-readable form:

Sample blog system authorization hierarchy
The turquoise boxes represent roles, the yellow box is a task, and the most fine-grained level of the authorization hierarchy - operations - are tan. Collectively roles, tasks and operations are called authorization items. You should keep in mind that functionally all auth item types are equal. It's completely up to you to make some auth item a role or a task - still it would do the same thing. Different types of auth items are introduced solely for the purpose of naming convenience. You are not limited to the three authorization levels: there can be multiple levels of roles, tasks and operations. (Getting back to our diagram, you can see this point illustrated by multiple levels of roles.) Also you may skip any of these levels (the role author has immediate child operation create). The only restriction is that in the auth hierarchy roles should stay higher than tasks and tasks should stay higher than operations.

Now let's take a quick look at what was on blog system creator's mind. Everything seems to be quite logical. The weakest role is reader: the only thing he is allowed to do is to read. An author has a bit more power: he also can create posts and update his own posts. Editors can read posts and update (edit) all posts, not own ones (in fact, according to the hierarchy, editors can't create posts and that's why editors haven't got any own posts at all). And of course, the most powerful role is admin which can do anything.

If you are familiar with the principles of object-oriented hierarchy, your former knowledge may lead you to a confusion. In every subsequent level of an object tree, objects obtain (inherit) all (or part) of the features of their parent (base) objects. This results in that bottommost objects are most "loaded" with features, while the root objects have only basic features. The opposite happens with RBAC hierarchy in Yii. The bottommost items in the authorization hierarchy represent basic operations, while the topmost authorization items (usually roles) are the most powerful and compound ones in the whole authorization system.

So now that the idea behind the hierarchy is clear, let's understand how the access checking works. To check if the current user as allowed to perform a particular action, you should call the the checkAccess method, for example:

if(Yii::app()->user->checkAccess('createPost'))
{
    // create post
}

How our hierarchy is used by Yii to check the access? Although you are not required to read this to understand the rest of the article, I provide here an example piece of Yii's code responsible for access checking (an implementation of CAuthManager for databases - CDbAutManager) for your reference:

if(($item=$this->getAuthItem($itemName))===null)
 return false;
Yii::trace('Checking permission "'.$item->getName().'"','system.web.auth.CDbAuthManager');
if($this->executeBizRule($item->getBizRule(),$params,$item->getData()))
{
 if(in_array($itemName,$this->defaultRoles))
  return true;
 if(isset($assignments[$itemName]))
 {
  $assignment=$assignments[$itemName];
  if($this->executeBizRule($assignment->getBizRule(),$params,$assignment->getData()))
   return true;
 }
 $sql="SELECT parent FROM {$this->itemChildTable} WHERE child=:name";
 foreach($this->db->createCommand($sql)->bindValue(':name',$itemName)->queryColumn() as $parent)
 {
  if($this->checkAccessRecursive($parent,$userId,$params,$assignments))
   return true;
 }
}
return false;

When you call checkAccess, Yii begins to recursively climb along the authorization hierarchy and check each item's business rule. For instance, when you make a call like this
Yii::app()->user->checkAccess('readPost')

Yii first checks the readPost's business rule (recall that an empty business rule is equivalent to a business rule always returning true). Then it searches for all readPost's parents - these are author and editor - and checks their business rules as well. The process doesn't stop when a business rule has been evaluated to true; it only stops when some rule returned false or we have reached the top of the hierarchy and there are no more parents to check.

So what are ways for the checkAccess method to return true? They are two. First, the iteration can stop with a positive result when Yii encounters in the hierarchy a so-called default role - a role that is assigned by default to all authenticated users. For our blog system this can be the reader role. Default roles can be set up in the web app configuration file; how this is done is described thoroughly in the Using Default Roles section of the tutorial.

The second way to make checkAccess return true is explicitly creating an authorization assignment which is basically defining an <auth item>-<user> pair. In code, this can be done like this:

$auth->assign('reader','Pete');
$auth->assign('author','Bob');
$auth->assign('editor','Alice');
$auth->assign('admin','John');

which is semantically equivalent to assigning roles to users. You're not limited to assigning roles; individual tasks and operations can be assigned to users as well. In real life, it is more practical not to hard code all auth assignments but to store them in a database. You can implement this scenario using the CDbAuthManager component which is described in the Yii tutorial.

Let's get back to the checkAccess discussion. Before hierarchy iteration begins, Yii collects all authorization items assigned to the current user and at each iteration step checks if current hierarchy's auth item is in the assignment list. If it is, the iteration stops and returns a positive result.

Assume we are implementing security for the "update post" user action. Whoever is logged in into our blog system should pass our authorization check before he is able to edit a post. Therefore the most appropriate place to check the access is the beginning of the respective controller action:

public function actionUpdatePost()
{
 if(!Yii::app()->user->checkAccess('updatePost'))
  Yii::app()->end();

 // ... more code
}

Suppose the current user is Alice. Let's see how Yii processes the auth hierarchy. Although updateOwnPost is an immediate parent of updatePost and returns false, Yii quickly finds another parent auth item which returns true - the editor role. As a result, Alice gets a permission to do a post update. What happens if Bob logs in? In this case the branch of the hierarchy going through the editor item is also processed but no item along it returns true. The only possible way for the access check to succeed is then to go through the updateOwnPost item.

But instead of an empty "always-true" business rule updateOwnPost has a more complex one (see the first code snippet at the beginning of the article) and for the evaluation it requires the post creator's ID. How can we supply it to the business rule? In the form of checkAccess's parameter. To achieve this we need to modify our controller action handler in the following way:

public function actionUpdatePost()
{
 // here we obtain $post, probably via active record ...

 if(!Yii::app()->user->checkAccess('updatePost', array('post'=>$post)))
  Yii::app()->end();

 // ... more code
}

Note that despite updateOwnPost returns true for Bob, the iteration through auth hierarchy still goes on. It only stops and returns success when it reaches the author item.

I think now you're able to figure out how Yii would check access given that Pete or John logged in.

Returning to the above code snippet, it may seem that we're providing the post parameter to the updatePost operation whose business rule is empty and requires no parameters at all. This is truth but not all of it. In fact Yii passes the same parameter set (there can be several parameters as they are passed as an array) to every hierarchy item at every iteration. If item's business rule requires no parameters, it simply ignores them. If it does require them, it takes only those that it needs.

This leads to the two possible parameter passing strategies. The first one is to remember for every auth item what other auth items can be reached from it in the hierarchy and provide each call to checkAccess with the exact number of parameters. The advantage of this strategy is code brevity and probably efficiency. The other strategy is to always pass all parameters to every auth item, no matter if they would actually be used for business rule evaluation. This is a "fire-and-forget" method which can help to avoid much of trial and error while implementing you app's security. Its downside is possible code clutter and maybe drop in script performance.

This is only basic information about the RBAC authorization model in Yii; much more advanced security models can be built using it. Please refer to The Definitive Guide to Yii and Class Reference for more details. Also there's a number of web interfaces implemented as extensions which can help you do the Yii RBAC administration.
more >>

Monday, January 17, 2011

Visual C++ 2010: How To Fix The "Up-to-date Project Always Gets Rebuilt" Problem

Sometimes when you hit F5 or F7, Visual Studio acts as if something has changed in your project and rebuilds it, even immediately after a fresh rebuild. This might be very annoying and time-consuming, especially when debugging big projects. I'll try to summarize what can be done to eliminate this problem.

It's all about the new MSBuild build system. Something is fooling it and instead of seeing in the build output window a message like this:

========== Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========

you always see this:

========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

The following can be done then:
  • Check your project settings regarding the intermediate output directory. If you have more than one project in your solution, no two projects can share the same intermediate output directory. No manually placed files should reside in this directory and no manual corrections to automatically generated files should be made. This directory should be exclusively under Visual Studio's control. Try to "Clean" the project or the entire solution using Visual Studio's command and then test the build behavior. If no luck then try to clean the directory manually and test again.
  • Your project might reference a non-existent file. MSBuild's up-to-date check mechanism will assume that a new build is required. Try to locate and remove non-existent files from the project.
  • Your project is converted from a project of a previous Visual Studio's version. And your project somehow became "broken". It also can "break" in some other mysterious ways during "normal use", even if it's not a conversion project. The cure is to re-create the project from scratch, despite how dull and tedious it may sound.
I personally encountered all the three above situations and managed to solve the problem. If you have something else to say regarding this topic please let me know.
more >>

Thursday, January 13, 2011

Visual C++ 2010: IDE Memory & Performance Problems. Consider Precompiled Headers

If all you need is just the PCH solution you can scroll down to “The PCH Solution” section immediately. Otherwise you may want to read about how I came to this solution and hopefully find some clue for solving your own problem.

Well, when I first installed Visual C++ 2010 I was full of anticipation and excitement about new IDE’s features. Certainly, with its IntelliSense technology Microsoft had gone far ahead of all its rivals. Visual Studio’s brand-new on-the-fly compilation and real-time error reporting capabilities drastically speed up coding and make the whole development process much easier.

Quite a bit of time has passed since then. I enjoyed the new extremely convenient IDE and kept on praising Microsoft for this incredible invention. But one day things began to get worse.

I noticed some strange IDE’s behavior. After a few minutes of editing the code the IDE was getting almost irresponsible, the window was failing to redraw fast and intensive HDD I/O was occurring. Something was happening and until it ends it was practically impossible to work. This effect started to appear more and more often. In some editing sessions I was getting it every 20 to 40 new lines of code.

I can’t point out exactly when it began. Maybe when I added a couple of headers containing some tricky macros. Or maybe when the line count in my entire solution exceeded some critical value.

All I knew it was about IntelliSense. Simply turning it off was not an option as without it the whole IDE would have lost all its appeal. No-o-o... I desperately needed IntelliSense, but a working IntelliSense!

My first step was using Google (sounds weird, huh? )) Soon I found that world falls into the following two parts. The first one is the people who are completely satisfied with new Visual Studio 2010 and have not even a single performance problem with it or a problem that can be solved relatively easily. The other world’s part is a bit unluckier and suffers from performance problems which seem mystical as Microsoft can’t do anything with them. Except referring people to absolutely useless solution checklists.

I read many blog posts, advices and other info and nothing helped. However I think some of those are worth looking at:

http://support.microsoft.com/kb/981741/en-us

http://weblogs.asp.net/scottgu/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx

Then I started monitoring CPU and memory usage via Process Explorer. It showed that the moments of performance drop relate to high physical memory usage followed by the massive flush to the page file. When I was typing the lines of code memory usage was growing gradually until the memory was totally flooded and Windows had no other way but to flush it to the page file. This explains intensive hard disk I/O which hindered the whole system’s performance. While all this was happening no CPU was being consumed at all. At the same time no particular process in Process Explorer was looking as a memory hog (although multitudes of vcpkgsrv.exe and msbuild.exe processes were spawning and dying all them looked pretty decent). Probably memory was being allocated internally by some system processes, I don’t know.

I must say I have Windows XP SP3 on my development machine. I searched for any information which could regard specifically to XP problems but found none. The next idea was to increase my RAM size. I had only 2GB and since I already did consider a memory upgrade just before these VS2010 problems it took me not long to decide. With 4GB of RAM things became better but not much. It still was hogging all the 4 gigs to the end and then flushing. Only these “hog-flush” loops got longer allowing me to type a bit more code.

Then I tried things such as:
  • Turning off/on and tweaking various options in the Tools\Options\Text Editor\C/C++\Advanced section. Didn’t help...
  • Turning on Diagnostic Logging (located also in the above mentioned section) with various verbosity levels and trying to look for any errors. Grrrrr, errors were found but too cryptic to give me a clue...
  • Rearranging code in files and recreating project/solution files. No luck...
  • Refactoring my most tricky macros. Nothing...
  • Installed Visual Studio 2010 Service Pack 1 Beta. Didn’t help
The PCH Solution

I kept trying and finally found the solution! This is it:

http://blogs.msdn.com/b/vcblog/archive/2010/01/26/precompiled-header-files-in-visual-studio-2010.aspx

Although it doesn’t contain a direct indication to my memory problem, these two phrases made me to start exploring:
“The intellisense compiler can load these iPCH files to save not only parse time, but memory as well: all translation units that share a common PCH will share the memory for the loaded PCH, further reducing the working set.”
“iPCH and build compiler PCH share the same configuration settings (configurable on a per-project or per-file basis through  “Configuration Properties->C/C++->Precompiled Headers”).”
The fact is when I started my project I took decision not to use precompiled headers at all. First, because at that time it was of course a very small project. Second, I thought I’d better have more flexibility as to header inclusion and therefore every translation unit would only have a minimal set of headers required for the compilation.

But time has passed and now the project had grown to a moderate size of ~40K lines of code and uses STL and 7 other 3rd party libraries some of which are quite big.

It took me about an hour to study the details and set up the whole PCH thing which involved rearranging includes in every file and changing the project settings. The following info helped me much and I suggest reading it thoroughly:

http://www.cygnus-software.com/papers/precompiledheaders.html

http://msdn.microsoft.com/en-us/library/z0atkd6c.aspx

And this is what I’ve got now:
  • No memory flooding problems
  • IntelliSense is working smo-o-o-thly
  • Compilation became blazingly fast
  • Piece of mind
Wish your VS2010 problems got solved!
more >>

Thursday, November 4, 2010

Getting Boost.Regex + Unicode to work with Microsoft VC++ 2010

[ This article pertains to Boost version 1.44. It may or may not remain useful in the future, when newer Boost versions appear, depending on how Boost.Regex’s developers would arrange the build process. ]

Although the subject above may seem to be overly specific, I think many people might want to use regular expressions with international text support in their programs being developed in Windows/Microsoft environment. I’m in no way a Boost.Regex expert or even seasoned Boost user. I just would like to share my “newbie” experience with programmers who are trying to achieve the same as I did. And for the current Boost’s version - 1.44 - it is not so easy.
And one thing should be mentioned before we start. I adhere to the principle of least resistance. For the process of software library linking that means the following: use vendor-supplied compiled binaries as much as you can and use your hands as sparingly as you can. Probably the moment when you need to build a library from sources (which can be quite troublesome) or do some manual tweaking will come. Maybe, but it’s a future, so leave all hassles for that future. For now we are going to get our libraries up and running, and to do it fast. At least on Windows platform, this approach seems to be sound.

OK, let’s start. As it’s noted here, to support Unicode you have two approaches: the simple one and the good one. For some cases the simple approach can suffice however actually it is not portable and has several disadvantages. To help you build a true Unicode-aware application, Boost.Regex - one of the best regular expression libraries - requires ICU – one of the best Unicode libraries. The following describes how to get Boost.Regex and ICU work together.

First we need to obtain the latest release of ICU from here. In the download page choose ICU4C as we need to interface the ICU library with C/C++ programs. Download the Windows binaries .zip file and unpack it to some folder on your hard drive, say C:\Distr\icu.

What we need to do in order to build Boost.Regex with ICU is described in detail here. However building from scratch is still not a preferred option, and when I was looking for an alternative I came across the BoostPro Installer which can provide us with binaries for every possible Boost library, every compiler, threading model, etc. But… BoostPro does not cover per-library specifics such as ICU-enabled Regex.

Therefore we have no other choice but to compile Boost.Regex by hand. However BoostPro Installer still can be of use for us because it can serve as a convenient download tool that will provide us with Boost sources and (what is more important) some compiled Boost tools (you will be able to see below why we need them). For now run BoostPro and proceed until the wizard page appears where compilers and variants can be selected. There you should select no checkboxes at all. On the next page leave only four checkboxes checked at the top of the list. Then advance to the end of the wizard and wait for files to be downloaded and installed.

Assume you chose to install Boost to the default installation folder (C:\Program Files\boost\boost_1_44). In the C:\Program Files\boost\boost_1_44\libs\regex\build folder you will find several vc*.mak files which – what a pleasant surprise! - outnumber those mentioned in the documentation on the Boost's web site. But what is not so good surprise is that they lack one for MSVC10. Running vc9.mak by VC10’s nmake.exe gives many errors and unknown option warnings which look a bit scary. Editing makefiles manually is not an option for us as we need the result as soon as possible.

Somehow guys at BoostPro had managed to built Regex library with MSVC10 and are unlikely to conceal their secret knowledge from the public, so it has to be somewhere around. In Boost.Regex’s build folder there are also some .sh files which are Unix shell scripts, a .cpp file and a cryptic Jamfile.v2. Relating this name and the information obtained from Regex’s building guide lets us conclude that we need a program called bjam (which in fact is a part of Boost’s own build system) to run Jamfile.v2. Fortunately, as a result of installation by BoostPro, a compiled bjam.exe can be found in the C:\Program Files\boost\boost_1_44\bin folder.

Now let’s launch a command line window and change the working directory to Regex’s build folder. The straight-forward (partially borrowed from the Regex installation guide and Google search results) command
"C:\Program Files\boost\boost_1_44\bin\bjam" -sICU_PATH="C:\Distr\icu" toolset=msvc-10.0 release threading=multi link=shared

among other info outputs an undesired message

has_icu builds : no,

which indicates that the test program has_icu_test.exe could not be compiled or linked correctly and the build script falls back to compilation/linking of Regex without ICU. After struggling for a while with this strange problem I found that by some reason the build tool requests for debug versions of ICU libraries which of course I have none of and didn’t intend to use. I must confess, I’m not fond of studying new software tools that I’m sure I wouldn’t use much on but here I had no other choice. Eventually I found that ‘lib’ rule sets select wrong alternatives, even when configuration features are explicitly provided via command-line arguments, just like in the command above. E.g. this block in the Jamfile.v2 file

   lib icuuc : : <search>$(ICU_PATH)/lib <link>shared <runtime-link>shared ;
   lib icuuc : : <toolset>msvc <variant>debug <name>icuucd <search>$(ICU_PATH)/lib <link>shared <runtime-link>shared ;
   lib icuuc : : <name>this_is_an_invalid_library_name ;

chooses the second line, i.e. the icuucd library (debug version of one of ICU’s libraries) but supposed to choose the first line, i.e. icuuc library (release version of that ICU’s library). Other rule sets behave in a similar way. I had no time to investigate why this may happen and I don’t see any reasons not to follow the path of least resistance and use a no-brainer: I commented out in the Jamfile.v2 file all alternatives which may lead to selection of incorrect libraries, like this:

   lib icuuc : : <search>$(ICU_PATH)/lib <link>shared <runtime-link>shared ;
#   lib icuuc : : <toolset>msvc <variant>debug <name>icuucd <search>$(ICU_PATH)/lib <link>shared <runtime-link>shared ;
#   lib icuuc : : <name>this_is_an_invalid_library_name ;
#   lib icudt : : <search>$(ICU_PATH)/lib <name>icudata <link>shared <runtime-link>shared ;
   lib icudt : : <search>$(ICU_PATH)/lib <name>icudt <toolset>msvc <link>shared <runtime-link>shared ;
#   lib icudt : : <name>this_is_an_invalid_library_name ;
#   lib icuin : : <search>$(ICU_PATH)/lib <name>icui18n <link>shared <runtime-link>shared ;
#   lib icuin : : <toolset>msvc <variant>debug <name>icuind <search>$(ICU_PATH)/lib <link>shared <runtime-link>shared ;
   lib icuin : : <toolset>msvc <variant>release <name>icuin <search>$(ICU_PATH)/lib <link>shared <runtime-link>shared ;
#   lib icuin : : <name>this_is_an_invalid_library_name ;

Mostly this is it. Save corrections to the Jamfile.v2 file and run the above command again. This should work the right way. My configuration for bjam was release threading=multi link=shared which means: I need release (non-debug) version, I need multi-threaded, I need DLL. You might probably want another configuration, then you may change release to debug, multi to single or shared to static.

When everything is going right, at the beginning of bjam’s console output you should see a message has_icu builds : yes.

As a result of bjam’s work, all generated files will be placed into the C:\Program Files\boost\boost_1_44\bin.v2\libs\regex\build\msvc-10.0\release\threading-multi folder (the last two subfolders can vary depending on your options).

To double check, you can examine a couple of .rsp files which also would reside in the output folder. E.g. the file c_regex_traits.obj.rsp should contain the line

   -DBOOST_HAS_ICU=1

And the file boost_regex-vc100-mt-1_44.dll.rsp should contain the lines

   "icuuc.lib"                   
   "icudt.lib"
   "icuin.lib"

That’s it. For how to use ICU-powered Boost.Regex please refer here
more >>

Monday, September 27, 2010

How to clean the heatsink and renew thermal compound in a Sony Vaio VGN-Z590 (VGN-Z Series) laptop

In this post I'll describe how a Sony Vaio VGN-Z590 laptop can be disassembled in order to clean its heatsink and renew CPU or other chips' thermal grease.

Make sure you have a set of jeweler's screwdrivers, a set of flat-tip and Philips screwdrivers and sufficient amount of CPU thermal compound. Also read the text thoroughly to understand if you need anything else. 

Note that preview pictures within this post are not only scaled down but also truncated from either side by Google Picasa and my circle or box markings are not always visible so you need to click on a photo to see it full size.

Okay, let's start with it. Shut down the computer, disconnect the DC power adaptor and remove the battery. Place the unit upside down.

Remove the 7 screws right on the bottom (red) and the 2 screws in the battery compartment (green). Then unscrew the memory lid (left yellow circle) and remove it, underneath the lid there’s the last screw securing the housing, remove that screw.

Turn the laptop over and open the lid fully. There’s a series of latches (red in the picture below) and metal hooks holding the keyboard panel along the left, right and front side of the housing. Use your nails or a plastic ruler to insert it between the keyboard panel and the middle frame and gently release the keyboard panel.

[ The middle frame is the grey colored panel containing the battery, HDD and wireless LEDs on the front side of the housing. ]

After the keyboard panel has been released you can lift it up however there’s the keyboard ribbon cable still holding it. Unplug its connector from the mainboard and finally remove the keyboard.

Next you will need to remove the middle frame. Note that the middle frame is a plastic structure of variable thickness, in some points very thin. A part of the middle frame contains an aluminum bracket attached to other parts by plastic rivets. So you must be very cautious when removing the middle frame.

First unscrew the 3 black screws (green in the photo below) holding the HDD and DVD drive and one another black screw next to the bigger HDD bracket (blue). Then remove the 2 silver screws next to the speakers (encircled by red). Next disconnect the HDD and DVD drive connectors from the mainboard (yellow) by gently pulling them up.

To remove the DVD drive you need to open its door. To do this with no electrical power supplied take a needle, insert it in the small hole (marked in the photo below) and push. The door will open. Pull the DVD drive carefully out of the housing.

Next remove the HDD along with the two aluminum mounting brackets holding it (red in the photo below) and the black rubber gaskets on its corners. Note that the brackets are captured by the series of plastic latches (green) which are below the HDD level and are not visible. Therefore you need to push up gently the entire assembly while rocking it slightly. Probably you’ll need an assistance of a flat-tip screwdriver to release the latches when you figure out where they are and how they hold the assembly.

What is still holding the middle frame are the latches next to laptop lid hinges. Two of these latches are covered with the two barrel-shaped side caps (shown in the photo below): one at the DC jack side and the other at the power button side.

To remove them use a bamboo skewer or flat-tip screwdriver, tip wrapped with one layer of soft insulation tape. These will let you avoid scratches and dents when you push the caps by the inner side in the directions indicated by the arrows in the picture above. See the following photo to understand where the latches are located inside the caps.

Once you removed the barrel caps you are able to release the following 3 latches (those two which were covered by barrel caps + one more) using a screwdriver or a thin ruler:

Then unplug the three white connectors indicated in the photo below. To do this grab the wire next to the connector and pull it carefully upwards gradually applying more and more force until the connector goes out of the socket.

Pull the cable corresponding to the biggest white connector out of the groove inside the middle frame (long box in the picture below). Then pull up the small ribbon cable (the small box in the lower left part of the picture below).

Now you can lift the middle frame and disconnect the ribbon cable still tying it to the mainboard by gently pulling it upwards (the box at the right in the picture below):

The middle frame is completely removed. Next we will release the mainboard.

Unplug the two white connectors (the two boxes at the left in the photo above).

Then disconnect from the motherboard the 5 ribbon cables marked with green in the photo below. To do so lift the small wide lock going at the top of the socket. This will release the ribbon cable. To release the sixth cable connecting the card reader board first you will need to remove the screw attaching the board to the housing. When you finished detach the ribbon cable as you did to other five ribbon cables. The card reader board cable and its screw are encircled with blue in the picture below.

Disconnect the 2 antenna cables (green in the picture below) by pulling them up off the antenna jacks. Release the light gray one from under the 2 adhesive tape pieces covering it (marked with yellow boxes). Then unscrew the female screw and the black screw (encircled with red).

Remove the 2 screws fixing the fan (green in the picture below). Lift up the phone jack (red) from the chamber in the housing. Now you can lift a bit the mainboard. Then you can detach the ribbon cable (marked with blue) connecting the network I/O board from the mainboard using the same technique you have used for other ribbon cables surrounding the mainboard.

At this point we’ve finished releasing the mainboard. We won’t disconnect it entirely.

Open the laptop’s lid to the maximum. Take a layer of thick cloth or soft packaging material and put it onto the LCD screen to prevent it from scratches. Then turn the mainboard around the wires still connecting it to the housing and lay it down to the screen.

There are 3 silver screws attaching the heatsink to the mainboard. Unscrew them:

Turn the heatsink assembly to the left around the adhesive tape glued to the heatsink exhaust and the fan. (we won’t remove this tape also.) While doing this be careful and apply moderate force as former thermal compounds can take some time to release the heatsink. Overly pulling the heatsink assembly can damage the chips it is attached to. If the heatsink can’t be released by a moderate force than use a hairdryer to make the old compound softer and then you will be able to detach the heatsink assembly from the chips easily.

The following photo shows the heatsink assembly opened. As you can see this side of the assembly covers the two chips.

After the heatsink assembly is opened you can begin cleaning. Vacuum clean the vents and the fan. Also you may use Q-tips to reach inaccessible areas. Clean until no considerable amount of dust left.

What is good for this laptop model is that the CPU has not to be removed from its socket in order to renew thermal compound. This minimizes the risk of damaging CPU’s pins and the CPU socket.

Remove the old pieces of thermal compound from the chips and corresponding heatsink areas. Finish by perfectly cleaning the surfaces with cotton swabs soaked in acetone or 99% alcohol.

Apply sufficient amount of thermal compound on each chip and evenly distribute it over the whole surface:

At this point the heatsink maintenance is over. 

Flip the heatsink assembly back to its place and replace the three heatsink screws. Then repeat the whole disassembly process in the opposite order.
more >>

Sunday, September 12, 2010

Ученые продолжают отвоевывать у природы разгадку тайны происхождения жизни

В химических системах с безразличным равновесием спонтанно возникает эволюция http://elementy.ru/news/431401 more >>

Sunday, August 1, 2010

Солнечная энергия дешевеет - Китай роняет цены

http://www.chaskor.ru/article/solnechnaya_energiya_desheveet_9983 more >>

Friday, June 4, 2010

Что угодно-с? Исчезнуть или стать Хаммером?

Гениальное по простоте идеи и, скорей всего, весьма сложное по схеме реализации оборонное новшество от израильской компании Eltics: камуфляжные панели с изменяемой температурой для дезинформирования IR-сенсоров.

Израиль научился делать танки невидимыми

YoutTube: Eltics "Black Fox" Thermal IR Countermeasure System [ShortVersion] more >>

Синтетические добавки к организму всё ближе

Исследователи создали компьютер из ДНК more >>

Friday, May 28, 2010

Инновации: что думают они там и мы здесь?

Мы здесь: Модернизация и стратегические риски путинского режима

Они там: Медведев позвал венчурный бизнес в Россию

Вроде, у всех есть основания. Все очкуют. И, на первый взгляд, ничего хорошего не последует. Мой прогноз: будет не так все плохо. Отчитаюсь в следующих постах. more >>

Tuesday, May 25, 2010

Ученые создали первую форму синтетической жизни

То неизбежное, о котором столько говорили, в которое многие не верили, а многие ждали, наконец, произошло. Это переворот в жизни человечества. Неопровержимое доказательство химического происхождения жизни найдено. Всплывут, как всегда, любители полемизировать, из-за которых поднимется неизбежное бурление г@вн, и, как следствие, прогресс в этой научной области замедлится, ну и черт (хых, а он есть? ;)) с ними, одолеем :))

Ссылки:

Новостная заметка в Wall Street journal: Scientists Create Synthetic Organism

Оригинал статьи: Creation of a Bacterial Cell Controlled by a Chemically Synthesized Genome

Обзор по-русски: Переломный момент с биологической и философской точки зрения

Цитата из оригинала:

"...If the methods described here can be generalized, design,
synthesis, assembly, and transplantation of synthetic
chromosomes will no longer be a barrier to the progress of
synthetic biology. We expect that the cost of DNA synthesis
will follow what has happened with DNA sequencing and
continue to exponentially decrease. Lower synthesis costs
combined with automation will enable broad applications for
synthetic genomics.
We have been driving the ethical discussion concerning
synthetic life from the earliest stages of this work (25, 26). As
synthetic genomic applications expand, we anticipate that this
work will continue to raise philosophical issues that have
broad societal and ethical implications. We encourage the
continued discourse."


Испытываю глубокое уважение и благодарность к участвовавшим ученым, потративших огромные силы и время на достижение этого поистине потрясающего результата! Они действительно пионеры нового мира...

Также могу добавить, но теперь без особой радости: из надежных источников стало известно, что после этого доклада к авторам уже наведались представители Пентагона. more >>

Wednesday, October 15, 2008

c2scan.com вышел в онлайн

Началось альфа-тестирование интернет-сервиса c2scan. Сервис представляет собой как самостоятельный проект, так и тестовую площадку для обкатки новой технологии обработки изображений ImgHog-2008. Эта технология, в частности, будет использована при реализации проекта Покупедия.ру.

Пока тестирование проходит среди ограниченной аудитории. Однако на страницах сайта можно уже сейчас ознакомиться с предварительной информацией о проекте. Также можно оставить свой email и запросить приглашение на публичное бета-тестирование.

Итак, поздравляем тебя с появлением на свет, www.c2scan.com!

more >>

Monday, August 25, 2008

Будущее BI в облаках?

Статья про начало конвергенции cloud computing и BI. Лично меня наиболее заинтересовала глава "Google + Panorama = BI 2.0?", в которой рассказывается об оригинальном решении компании Panorama в условиях, когда она осталась один на один с еще более укрупнившимися в результате недавних слияний BI-гигантами.

Ссылка: Будущее BI в облаках?

more >>

Friday, July 4, 2008

Зачем посылать SAP

Проект Покупедия.ру жив и здоров, однако в изменившихся условиях его таймлайн претерпел некоторые изменения. Появились новые этапы, и проект, по видимому, даст одно или более ответвлений, благо технологическое ядро может быть использовано многими способами. Сейчас, когда прошел долгий период сложной, но увлекательной работы, несмотря на то, что нужно еще очень много сделать, хочется перевести дух. Как раз в такие моменты оглядываешься назад и осознаешь многие вещи. Череда флешбэков встает перед глазами и ответы на вопросы, которые много раз задавал себе сам, кристаллизуются в голове. Почему SAP-консультант бросил SAP? И что он забыл в обработке изображений? Что ж, ответы не на два слова.

Работать я начал, как и многие в наше время, еще на старших курсах, пробуя себя то в web-программировании, то в области СУБД, то пописывая различные утилиты и системки. В то время всё для меня было новым и интересным, хотелось узнать побольше технологий, результаты своей деятельности приносили много радости. Часто, увлекаясь работой, я задерживался в офисе и вполне мог понять людей, которые приходили поработать в выходные. Но постепенно щенячий энтузиазм уступал место здоровому прагматизму и под его давлением я стал принимать «стратегические» решения.

Первое такое решение - прекратить быть «тупым кодировщиком» и начать заниматься «взрослыми вещами». Под «взрослыми вещами» я тогда понимал «большие» системы, иными словами КИС. «Программизм», как я считал, - занятие для «мальчиков», т.е. студентов и прочих социально неустроенных личностей. К числу последних я с сочувствием относил и множество виденных мной программистов, не способных объясниться с заказчиком без злоупотребления профессиональными жаргонизмами и совершенно не понимающих прикладной специфики. Особенно впечатляли меня не самые молодые из них: они оставляли у меня ощущение великовозрастных детей или засидевшихся девок.

Настоящее же дело - это когда сидишь рядом с заказчиком, разговариваешь на его языке и мудро выуживая информацию из своего богатого опыта, обильно сдобренного солидной теоретической подготовкой, решаешь проблемы компании-клиента. Планируешь архитектуру системы, продумываешь взаимосвязи между компонентами. Периодически ты сталкиваешься с задачами, которые еще не приходилось решать, и со смаком погружаешься в них, чтобы еще больше расширить багаж своего опыта. Ты становишься мостом между заказчиком и «несознательными программерами», умея говорить и на языке одного, и на языке других. Заказчик доволен проделанной работой, большие начальники в пиджаках сердечно благодарят тебя и жмут руку, все улыбаются. Ну, что-то в этом роде. Так мне это представлялось.

После некоторой борьбы с неподатливой судьбой, мне таки удалось нагнуть строптивую и претворить в жизнь свое первое «стратегическое» решение, на 90 градусов изменившее курс моей вяло дрейфующей карьеры. Но, как это часто бывает в жизни, по прошествии времени сияющий Грааль оказался невзрачной грудой глиняных черепков. Работа в области КИС оказалась довольно грязным и склочным дельцем. Несмотря на то, что мне лично пришлось заниматься, дай Бог, чтобы половиной вещей из моих мечтаний, весь процесс изнутри мне стал отчетливо виден. Я был консультантом, но понял, что работать методологом, аналитиком и даже самым-самым раз-начальником не сильно лучше. Не буду здесь расписывать подробно, какой это забавный бизнес, многие и так знают. А кто не знает и кому интересно узнать, то, как говорится, пишите в личку.

Ну, раз уж не суждено было видеть интересную работу и улыбки заказчиков, я принял еще одно «стратегическое» решение. Менять всё снова на 90 градусов и полностью уходить из области казалось глупым, поэтому я постановил, что буду просто зарабатывать деньги - чем больше, тем лучше. Как я теперь понимаю, это была моя серьезнейшая ошибка. Таким образом я лишь законсервировал нарождающийся внутри себя психологический кризис, который по прошествии некоторого времени набрал полную силу и принес мне немало моральных мучений. Тогда же казалось, что продолжить существование, проведя дихотомию «работа-неработа» - всего лишь дело техники.

Итак, «подымать бабло» я решил в области SAP. Я понимал, что SAP - это волшебная кормушка, единожды попав в которую, будешь обеспечен всю оставшуюся жизнь. Но на тот момент я являлся вполне сформировавшимся специалистом по совершенно другим системам, поэтому мне пришлось провести очередной раунд интенсивной борьбы с судьбой. Мой состав уже вовсю катился не по тем рельсам, но мне снова удалось вырулить на нужную колею.

Далее пошли, как это бывает с SAP-консультантами, внедрения, поездки в Сибирь, поддержки, документации и презентации. Через некоторое время до меня стало доходить, что, продолжая так работать, я начну морально и личностно деградировать, если уже не начал. Я понял, что когда проходит новизна освоения неизвестной системы, когда позади все обучения и первые запуски, ты становишься, по существу, дрессированной обезьянкой для внедрения. Из раза в раз ты применяешь свой минимально растущий опыт. Для компании ты - фактически commodity, основное средство с определенной ежемесячной стоимостью владения, черный ящик для генерации прибыли. И компании абсолютно пофигу, если ты хочешь полностью реализовать свой потенциал или заниматься интересными задачами. Позднее мой будущий босс Смелянский Руслан Леонидович скажет: «Как это ни цинично звучит, бизнес не заинтересован в развитии личности. Он заинтересован в ее эффективной отдаче.» И это осталось бы верным, даже если бы я ушел в совершенно другую организацию заниматься совершенно другими вещами.

Я начал пытаться параллельно к основной работе создавать свои собственные проекты. Сначала они были довольно наивными, затем становились более серьезными. И тем более сложно их стало совмещать с работой. Кто бывал в такой ситуации - тот знает. Конечно, в основном, мои проекты больше приносили интерес, чем приличные деньги. Основная работа постепенно становилось совсем невмоготу. Каждое утро и каждый вечер я мужественно преодолевал под землей почти всю Москву наискосок, придавленный мрачными мыслями о том, что, ё-моё, сколько ж времени пропадает зазря и что мне уже почти 30 лет, а своё место в жизни так и не найдено. Свой моральный кризис я уже вполне осознавал, но бросить всё в одночасье было невозможно, требовалась подготовка.

Как и многое в жизни, проект Покупедия.ру начался со случайности. Не буду даже уточнять, кто и как именно, но случайные люди и случайные события привели к возникновению мысли, что неплохо бы сделать сервис, который бы позволил фоткать чеки из магазина и уже, в конце концов, решить задачу удобного ввода данных в свой личный бюджет. Задача показалась мне вполне решабельной, а собственная история попыток упорядочить личные финансы намекала на то, что сервис был бы очень полезен. Буквально через несколько дней вышел очередной номер Компьютерры, в редакторской колонке которого черным по белому почти слово в слово повторялась эта идея. Нужно ли говорить, что это событие послужило большим толчком к началу моей деятельности?

К тому моменту я абсолютно ничего не смыслил в обработке изображений, а заложенный в период обучения в Университете багаж математических знаний был порядком выбит из активного отдела мозга малоинтеллектуальными задачами из повседневной жизни типового айтишника. Решиться сделать первый шаг было непросто. Я понимал, что тема сложная и, в любом случае, она окажется еще сложнее, чем я предполагаю. Несколько дней я просто думал, стараясь увидеть преимущества и недостатки идеи, представить свою работу над проектом. В итоге я решился, и вот почему:

- Проект технологичен и наукоемок. Сейчас столько развелось стартапов а-ля «Видео за фантик» или «Социальная сеть ковыряющих в носу», что, во-первых, такими заниматься просто неинтересно, а во-вторых, они элементарно копируются. Здесь же есть где поупражнять свой мозг, да и хрен скопируешь. Во всяком случае, не так быстро.

- Я всегда тяготел к науке, но не хотел заниматься ей как это сейчас принято. В пользу первого говорит то, что я стал аспирантом на своей кафедре, в пользу второго - что я так и не дошел до написания своей диссертации. Кандидатский минимум и одна статья - вот максимум, на который меня хватило. Стиль жизни и размер оплаты на кафедре оказывали на меня удручающее впечатление и я смалодушничал, полностью уйдя «на заработки».


- Суть этого проекта - инженерия, т.е. стык науки и практики. Для меня такая работа - самый лучший вариант, хотя понял я это относительно недавно. Когда ты добиваешься видимого и полезного результата, применяя научные методы, которые понимаешь почему и как работают - это непередаваемое ощущение. Работа на кафедре выглядела бы намного более сухой, теоретической и абстрактной.


- Меня всегда интересовал вопрос: вот, допустим некоторые учатся, скажем, на физика, и идут работать программистом. Или еще лучше, учатся на геологическом, а заканчивают менеджером по продажам. Куда идут полученные знания? В канализацию? Мне могут ответить, что вуз, прежде всего, учит учиться, получать информацию, общаться и выполнять работу. Ну, хорошо, но все же, целый пласт специальных знаний - он же практически пятидесяти процентам из нас так и не пригодился в работе. Вам не жалко целых пять лет жизни? Мне - жалко, тем более, что образование я получил одно из самых лучших - ВМиК МГУ. Почти всегда главной целью обучения в вузе являлась казенная корочка под названием диплом. В данном же случае, «богатство, которое всегда с тобой» имеет шанс действительно стать твоим сильнейшим конкурентным преимуществом.


- Обработка изображений, да и, вообще, любых сигналов, а также примыкающие сюда дисциплины, например, распознавание образов - очень перспективная область. Она сложна, высокотехнологична и за ней - будущее, т.к. без нее невозможен полноценный сплав ИТ с человеком, который, несомненно, является и будет являться преимущественным направлением исследований во всем мире.

Прошел почти год с начала работы над проектом. За это время мне пришлось огромными кусками с увлечением заглатывать недостающие знания и освежать подзабытое. Много из того, что когда-то было кое-как сдано в сессию - лишь бы сдать - сейчас приходилось проходить заново, только уже с полным пониманием, зачем это нужно и с куда большим удовольствием. Во многих областях стала складываться по-настоящему целостная картина, чего я не мог достичь, учась на факультете. Сначала разработка велась урывками, в свободное от основной работы время. Затем удачное стечение обстоятельств позволило мне, наконец, покинуть ненавистную работу и посвятить себя проекту практически полностью.

Совсем ли я распрощался с SAP-ом? Я надеюсь, да. Ну, разве что, если нужда припрет - тут уж ничего не поделаешь. А так, думаю, что да. Да и примерно то же я думаю про любую наемную работу.

А не были ли прошедшие годы бесполезными? Ну, разве что только последний, когда я вообще перестал узнавать что-то новое и совсем стал мартышкой для внедрения. А остальной опыт мне весьма и весьма пригодился и еще не раз пригодится, я уверен. Я узнал многое, например, об архитектуре систем, и намерен это использовать в своей дальнейшей практике. Ну, и надо бы и дальше держать руку на пульсе SAP и мониторить, что же там у них происходит: компания, что ни говори, весьма интересная.

И кто знает, может, я, все-таки, защищу кандидатскую? Уже в области обработки изображений :)
more >>

Как относятся к нам и к нашей работе работодатели?

Да, я понимаю, блоггер я - никакой. Конференция REMIX, на которой я был, давно уже прошла, а баннер я снял только сейчас. Последний мой пост датируется началом апреля, а сейчас - уже начало июля. Тем более, подумав немного, я решил, что снабжать сообщество какой-либо новой информацией о REMIX нет смысла, ибо и так уже немало написано, и всё по делу. Чёрт возьми, даже про SAP у меня никакого желания писать нет. Удивительно, что порядка тридцати подписчиков до сих пор остаются со мной. Видимо, люди поверили в то, что от меня может исходить интересная и полезная информация, и предпочли остаться со мной. Спасибо Вам! Буду стараться не разочаровать Вас. Хотя и тематика моего блога изменится, надеюсь, что всем Вам будет интересно.

Итак, я хочу попрощаться со своим корпоративным прошлым.

Первый факт. Мое предыдущее место работы: MAG CONSULTING. Как там дела? ИТ-менеджер заперся в офисе и требует денег

Второй факт. Мое предыдущее место работы: Microtest. Как там дела? Знакомьтесь, это - SAP BW, OLTP-система (проект РЖД №1: КАК+ПОЧЕМУ)

Про последнее место работы, REDLAB LTD, - поподробнее. Какое-то время назад я имел разговор с руководством о том, чтобы не разглашать наиболее вопиющие факты деятельности этой конторы, но, по прошествии некоторого времени, подумал: а какого чёрта?! Ведь именно из-за молчания обделенных и обиженных такие фирмочки могут безнаказанно продолжать свою довольно сомнительную деятельность. Когда я только устраивался на работу в REDLAB, я переходил из компании, в которой были проблемы с выплатой зарплаты. Поэтому я прямо спросил на собеседовании начальницу отдела КИС Коноплёву Е.Ф.: «А как у вас в компании с выплатой зарплаты? Всегда ли вовремя? В полном ли объеме?» Меня заверили, что все в полном ажуре и беспокоиться абсолютно не о чем. Что бывают задержки платежей от клиентов, но компания мудро буферизует такие проблемы и зарплата выплачивается всегда в срок и в полном объеме. Дело было в начале мая (обратите внимание!).

Через две недели наступает корпоративное собрание, на котором задают вопрос: «Когда выплатят долги?» На этот вопрос отвечал мудрый вождь РЕДЛАБа Смелянский Руслан Леонидович (являющийся, насколько я знаю, еще и профессором на ф-те ВМиК МГУ, который я имел честь закончить; об этом персонаже, видимо, еще будет иметь смысл сказать пару слов ниже). Поигрывая ключами от Audi A8 (мне так сказали, может, и неправда; я только смог понять, что эти ключи - от дорогой машины) и обильно пересыпая свою речь архаичным союзом «поелику» (надо сказать, звучало довольно по-идиотски) он заявил примерно то, что да, уже с февраля (помните, мне в мае сказали, что проблем с зарплатой нет) идет задержка зарплаты, платить пока не будем, не нойте, позже выплатим. Ну, что ж, мне пришлось утереться. Меня просто натянули на собеседовании, как мальчика. Обещания о выплате я слышал еще о-о-чень много раз. И с рявканьем уже отстать наконец, и с посулами выплатить уже вот-вот через неделю, и с обещаньем того, что топ-менеджмент не будет получать зарплату, пока не будет погашена задолженность. И каждый раз это сопровождалось поглаживанием лоснящегося животика и поигрыванием ключами от дорогой машины.

Да чёрт с этим животиком и этой машиной, в конце концов! Проблема была в том, что сначала просто никто не думал, что проблема так затянется, а потом понимал, что накопившийся долг уже никогда не получишь, если уволишься. Получался замкнутый круг. Поэтому когда произошел первый существенный возврат долгов (да! через полтора года!) ваш покорный слуга сразу же написал заявление. Причем долги еще остались, и мне их не вернули, но я предпочел уйти и распрощаться с этой конторой навсегда.

У меня остались теплые чувства к коллективу, с которым я работал (но не к начальству!). Все они в той или иной степени заложники РЕДЛАБ: одни областные, другие возрастные, третьи студенты и проч. и проч. Только используя слабое положение сотрудников и ставя их в заведомо худшие по сравнению с рынком условия, РЕДЛАБ еще как-то держится на плаву. Ему не помог ни переход под крыло Компьюлинка, ни насильственный (против воли большинства сотрудников) перенос офиса за МКАД в более дешевое место.

Кстати, забавно, но именно с проблемой долгов в РЕДЛАБ связано появление надписей -ЦЕНЗУРА- в моем блоге. Дело в том, что когда нам чуть ли не на Библии поклялись, что выплатят долги в январе 2008 года, я поверил руководству и начал готовить материалы по проекту РЖД, на субподряде в котором я работал до того времени. Видит Бог, ничего крамольного там не было, но я решил, что лучше все это публиковать под конец. Надо признать мое поведение довольно глупым, ибо руководство, как всегда, свое обещание не сдержало, а со временем кто-то наткнулся на мой блог, и я был вызван на ковер. Я реально рисковал лишиться денег, которые мне задолжала компания. Сейчас, конечно, смысла ничего скрывать нет, и надпись -ЦЕНЗУРА- скоро исчезнет :) Но вот всем урок: откровения оставьте на «самый потом», когда терять уже нечего.
more >>

Friday, April 18, 2008

Встречайте - проект Покупедия.ру

Получается, уже более месяца в этом блоге не появлялось новых записей. Причины - более чем уважительные: уход с места работы под названием РЕДЛАБ, обустройство новой жизни, но главное - работа над новым проектом. Для меня этот проект, конечно, уже давно не нов, но вниманию публики он был представлен впервые.

Мероприятие, где был представлен мой проект, прошло 9 апреля 2008 года в Московской международной высшей школе бизнеса МИРБИС и называлось Первая презентационная сессия инновационных проектов "ИТ Альянса". "ИТ Альянс" - не просто какое-то объединение IT-шников, как можно было бы понять из названия, а на самом деле, это аббревиатура от "Инвестиционно-технологический альянс". Более подробно об этой молодой, но представительной структуре можно прочитать, например, здесь. Пока же замечу, что инициатором ее создания выступило Национальное содружество бизнес-ангелов (СБАР), и кроме него туда входят компании Intel, Microsoft, венчурные фонды ABRT, Oradell Capital и еще большое количество фондов и компаний.

На сессии присутствовали представители всех входящих в "ИТ Альянс" организаций, в том числе, и тех же Intel и Microsoft. Сама сессия являлась, скорее, мероприятием закрытого формата. Хотя после ее проведения в Сети и появились отчеты (например, здесь), я, как человек лучше знакомый и с самими представленными проектами, и с работой СБАР, могу согласиться не со всем, что там написано, а иногда совсем не могу согласиться :) Возможно, я еще напишу обзор этого мероприятия целиком, но сегодня я хочу дать краткую информацию только о своем проекте, так сказать, из первых рук.

Да, и пока я не начал, хотелось бы выразить благодарность всем сотрудникам СБАР, в частности, отдельное спасибо Александру Комарову, начальнику отдела инвестирования и Александру Каширину, председателю правления. Их вклад трудно переоценить, без их усилий путь проекта к инвестиционной стадии был бы трудным и извилистым.

Итак, приступим.

Одним из инициаторов проекта (а именно, вашим покорным слугой) разработан действующий прототип так называемого­­­­ ядра обработки изображения, позволяющего подготовить фотографии текстовых документов к дальнейшей обработке стандартными программами распознавания текста.

Все существующие на сегодняшний момент программы распознавания текста рассчитаны на работу со сканированными документами. С обычными фотографиями текстовых документов такие программы либо справляются очень плохо, либо не справляются вообще. Причинами этого являются как наличие на фотографических изображениях геометрических искажений, связанных с положением фотокамеры, так и неравномерность освещения при фотосъемке.

Одним из вариантов практического использования разработанной технологии обработки изображений является проект Покупедия.ру. Интернет-портал Покупедия.ру включает в себя web-сервис и социальную сеть, работа которых строится вокруг интегрированной в портал технологии ввода данных о покупках пользователей.

С помощью web-сервиса пользователи могут проводить анализ качественного и количественного состава своих покупок, их стоимости и мест приобретения. Пользователи также являются участниками социальной сети, включенной в портал. Центрами общения между ними форумы обсуждения товаров, их производителей и мест покупок.

Для работы web-сервиса и социальной сети каждый пользователь должен регулярно вносить информацию о своих покупках. Ввод этих данных вручную практически нереален, поэтому ключевым фактором здесь является технология ввода информации: фотографирование кассовых чеков. Вот как она будет работать:

  1. Пользователь делает фото чека.
  2. Далее через сайт сервиса пользователь отправляет фото для обработки на сервер.
  3. На серверной стороне из фото чека извлекается текстовая информация.
  4. Результат обработки через сайт демонстрируется пользователю. Если необходимо, пользователь может внести исправления или дополнения.
  5. Информация о покупках пользователя попадает в закрытую базу данных и становится готовой для дальнейшего использования.
Следует подчеркнуть, что вся обработка изображений производится целиком на серверной стороне, что позволят надежно защитить от копирования как сам сервис, так и технологию.

Пользователи Покупедии получают следующие возможности:
  • Становится очевидным объем и состав своих расходов.
  • Наличие истории покупок позволяет спрогнозировать, сколько и на что будет потрачено средств в будущем.
  • Механизм ввода данных через распознавание кассовых чеков позволяет учитывать товары, автоматически снабжая их целым рядом категорий. Кроме анализа структуры расходов, это позволяет реализовать, например, такую полезную функцию, как список покупок, который можно взять с собой в магазин.
  • Пользуясь отзывами и участвуя в обсуждениях, потребитель решает задачу выбора товаров и получения рекомендаций.
  • Данные о покупках других пользователей дают возможность находить наиболее выгодные цены и улучшать качество товаров в личной потребительской корзине.
Несколько слов о том, что послужило предпосылками к созданию проекта. Сегодня в нашей стране наблюдается явление, которое можно назвать "потребительский бум". Поэтому перед потребителями встает ряд проблем:
  • Во-первых, часто задача выбора конкретного товара из товарной категории становится трудно решаемой.
  • Во-вторых, появляется желание четко оценить количественный и качественный состав приобретаемых товаров.
  • И в-третьих. Выбирать товары и магазины помогают рекомендации. Люди, которые могут их дать, существуют, но мы их не знаем.
Важно отметить, что одновременно происходит и будет происходить увеличение числа пользователей Интернет.

Проект Покупедия.ру появился как ответ на такую ситуацию.

Коммерциализация сервиса возможна сразу по нескольким направлениям. Во-первых, это реклама на сайте. Наличие информации о покупках пользователей позволит сделать ее таргетированной.

В результате работы сервиса будет накапливаться информация о приобретенных пользователями товарах. На этом факте основано второе направление коммерциализации - проведение заказных маркетинговых исследований. Для соблюдения морально-этических норм используемые данные будут обезличены.

Также возможна организация рекламных акций совместно с производителями товаров и торговыми предприятиями. Примерами могут послужить программа распространения купонов со скидками или программа розыгрыша призов.

Информация о подробностях и ходе проекта Покупедия.ру будет постоянно появляться на страницах этого блога. Прошу вас, если возникают вопросы или предложения - не стесняйтесь, задавайте и вносите. Замечу заранее, что один вопрос - а именно "зачем все это консультанту по SAP?" (в скобках замечу, вполне успешному и неплохо получавшему) - и еще несколько примыкающих к нему вопросов я в будущем собираюсь обсудить отдельным небольшим постом.
more >>

Friday, March 14, 2008

SAP BW: Муки рождения

Часто от многих людей можно слышать один и тот же вопрос: "Зачем SAP нужно было создавать с нуля систему хранилищ данных и весь инструментарий Business Intelligence, когда на рынке уже существовали производители, предлагающие целый ряд сложившихся продуктов такого класса?" Ответить на это будет довольно просто, если мы сначала взглянем на историю развития SAP в области отчетности, анализа и управления данными. На самом деле, у SAP уже существовали наработки, частично или полностью реализующие такую функциональность в составе системы R/3. И если мы проследим эволюцию этих инструментов, то поймем, что решение о создании отдельного продукта было принято не за один день.

Началось все с разработки внутри R/3 так называемого слоя информационных систем - уровня абстракции, который позволял упростить создание различных отчетов на базе OLTP данных. Этот уровень абстракции появился в R/3 очень давно - еще с версии 2.0 (напомню, что текущая версия 7.10). Однако проблема состояла в том, что реализация слоя информационных систем очень разнилась в различных частях системы. Например, Информационная система логистики (Logistics Information System, LIS) имела один набор инструментов доступа к данным, называемый standard and flexible analysis, в то время как Информационная система персонала (Human Resources Information System, HRIS) имела совсем другой набор инструментов, реализованный с помощью отчетов. Разработка каждой из этих частей системы велась отдельной командой. И хотя такая узкая специализация позволяла создавать более продуманные решения с точки зрения разработки, разность подходов создавала довольно большие проблемы в процессе внедрения.

Во-первых, в информационных системах сильно отличались структуры данных и методы доступа к ним, поэтому для их настройки и администрирования требовались разные специалисты. Второй аспект уже касался конечных пользователей. Дело в том, что в зависимости от прикладной области, в которой изначально обрабатывались данные, пользователи были вынуждены изучать и использовать разные инструменты доступа. Во многих случаях на вид простые отчеты приходилось реализовывать в виде целого набора отдельных отчетов или писать специальные ABAP-программы. Все это вызывало у заказчиков огромное разочарование и, в конечном итоге, выливалось в существенное удорожание и затягивание внедрений. К примеру, примитивный отчет, в котором напротив каждой строки заказа должна стоять сумма текущей задолженности перед поставщиком, реализовывался посредством двух различных информационных систем.

Первая разработка, созданная SAP целенаправленно в области OLAP, называлась аналитический процессор (research processor). В начале 90-х этот инструмент использовался в подмодуле Анализ прибыльности модуля Контроллинг (Controlling Profitability Analysis, CO-PA). Аналитический процессор позволял создавать многомерные отчеты по прибыльности и организовывать просмотр таких отчетов на различных уровнях агрегации. Этот инструмент существует в R/3 и поныне, нося название сквозная отчетность (Drill-Down Reporting). Повсеместному распространению возможностей сквозной отчетности внутри R/3 способствовал постоянно растущий спрос на многомерную отчетность со стороны пользователей системы.

Итак, в определенный момент SAP осознала ситуацию, в которой оказалась. С одной стороны, компания уже обладала рядом очень мощных аналитических инструментов, реализованных в R/3. С другой стороны, существовала масса клиентов, которым были остро необходимы инструменты для анализа данных. На почве этого неудовлетворенного спроса процветал целый ряд производителей продуктов Business Intelligence, а SAP теряла клиентов, обладая при этом всеми компетенциями, необходимыми для создания полноценного решения в области хранилищ данных.

Результатом такой ситуации стало решение создать так называемый Аналитический сервер (Research Server), который позже и получил имя SAP Business Information Warehouse (SAP BW). (Кстати, думаю, многим консультантам SAP BW всегда было интересно, почему все, что связано с BW - транзакции, пакеты, функциональные модули и проч. - имеет префикс RS; так вот и ответ на этот вопрос). Эта инициатива стала самым крупным проектом разработки в истории SAP, не считая, конечно, системы R/3. В первой половине 1997 года SAP отобрала пять компаний-клиентов для проведения пилотных внедрений SAP BW. В начале 1998 года для дополнительного анализа технических требований и проверки продукта "в полевых условиях" среди уже шести клиентов была запущена так называемая Программа первых клиентов (Early Customer Program, ECP). Самой известной компанией, принявшей участие в этой программе, была корпорация DEC (Digital Equipment Corporation). В сентябре 1998 года SAP BW версии 1.2A стал доступен всем остальным клиентам. Вот таким образом и состоялось рождение BW.

Думаю, никогда при проектировании SAP BW не вставал вопрос использования какой-либо сторонней OLAP разработки. Скорей всего, без долгих колебаний было принято решение просто перенести целый ряд концепций из R/3 и воспользоваться существующим опытом. Двумя яркими примерами концепций BW, изначально реализованных в R/3 (имеются в виду именно концепции, а не сам программный код), могут стать система раннего предупреждения (Early Warning System) и интерфейс "отчет-отчет" (Report-to-Report Interface). Первая из этих концепций позволяет устанавливать пороговые значения или условия, при достижении которых система выдает сообщение с предупреждением. Например, такая возможность может использоваться для мониторинга состояния складских запасов. Пользователь устанавливает минимально допустимое количество единиц на складе и временной интервал, по которому система будет производить проверку. При достижении установленного порогового значения система автоматически уведомит ответственное лицо о том, что нужно отправить поставщику заказ для пополнения складских запасов.

Вторая концепция, интерфейс "отчет-отчет", позволяет пользователю удобно перемещаться по различным отчетам. Например, финансовый контролер занимается анализом себестоимости в прошлом отчетном периоде. Вдруг он встречает существенное отклонение от плановых значений. Его интересует, повлияли ли на это изменение расходы маркетингового подразделения. В этом случае он может просто выбрать функцию перехода в отчет анализа маркетинговых расходов, который будет открыт для того же периода того же финансового года, что и исходный отчет. Такой подход позволяет исключить лишние действия пользователя по открытию второго отчета и повторному вводу параметров.

Мы рассмотрели лишь две концепции, перенесенные из R/3 в BW. В действительности их намного больше. Выходит, что еще до создания BW, компания SAP имела многолетний опыт построения OLAP инструментов и решений для управления данными. И этот факт совершенно нельзя сбрасывать со счетов при рассмотрении SAP в качестве производителя продуктов Business Intelligence и систем хранилищ данных.

При подготовке материала использовались следующие источники:

  • K. McDonald, A. Wilmsmeier, D.C. Dixon, and W.H. Inmon. 2002. "Mastering the SAP Business Information Warehouse". Wiley Publishing, Inc.
  • N. Hashmi. 2000. "Business Information Warehouse for SAP - Your Guide to Data Warehousing and BW". Prima Publishing
  • help.sap.com

more >>