خوب این اولین بار نیست که همچین چیزی رو میبینیم. نمونهی بزرگتر (از نظر کارایی) لایبرری om هست. این لایبرری در حقیقت به برنامه نویسهای کلوژراسکریپت اجازه میده با react کار کنن. (به جای اینکه لازم باشه به روش javascript interop کد بزنن و اسامی کلاسها و توابع react رو بنویسن و صدا بزنن)
راندمان پروژههای om نسبت به مشابههاش که با react توی js نوشته شدن، تقریبا دو برابره.
این مساله رو یک بار rick hickey توی یکی از تاکها گفت. بعد از تاک چندتا از برنامه نویسهای خود react (سازندگانش) رفتن سراغ ریچ هیکی و باهاش صحبت کردن ببینن قضیه از چه قراره 
چندتا ورژن بعد، راندمان react بیشتر شد (با تشکر از رهنمودهای ریچ هیکی) ولی هنوزم به نسخهی کلوژریش نمیرسه.
(این صحبتها رو خود ریچ هیکی توی یکی از کنفرانسها گفت فکر میکنم برای سال ۲۰۱۵ بود)
قضیه اینه که کلوژر به شما اجازهی کدنویسی به روشهای غلط رو نمیده. پارادایمهایی که توی ساخت کلوژر درنظر گرفته شدن، همشون با دقت انتخاب شدن. مثلا همین قضیهی immutable بودن همهی دیتاتایپها بجز atom به شما اجازه نمیده دیتاها رو پاک کنید و از اول بنویسید (و یه تایمی از پردازنده گرفته بشه برای gc و reallocate کردن رم) و در عین حال اگه واقعا نیاز به نگهداری state هست (مثل app-db توی re-frame که این هم لایبرری برای ساختن اپهای react هست) میتونید از atom استفاده کنید.
و این بخشهای mutable و بخشهایی از کد که side effect دارن رو (همونطور که توی آموزشها میبینید و یاد میگیرید) میذارید یه گوشه که وسط کدهای تمیز و pure function نباشه. (یه جور لایهی abstraction میسازید بین کدهای هستهای و کدهایی که قراره لاگ بگیرن یا محتوایی رو به کاربر نمایش بدن)
بگذریم. بیشتر قضیه همینه.
یه بخش دیگش نحوهی نگهداری دیتاتایپها روی رم و نحوهی دسترسی بهشون هست. (توضیحش یه کم سخته امیدوارم واضح بگم)
توی کلوژر لیستها (مثل array توی زبانهای دیگه) به صورت tree ذخیره میشن با branch factorی به اندازهی ۳۲. توضیحش سخته کشیدنش خیلی سختتر. ولی تصور کردنش سادست. ما هممون میدونیم binary tree چیه. همین درخت باینری رو درنظر بگیرید، به جای اینکه هر نود، ۲تا شاخه داشته باشه، ۳۲تا شاخه داره.
نتیجش این میشه که توی دیتاستهای کوچیک مثلا ۱۰۰رکوردی، تفاوت چندانی با binary tree نداره توی قضیهی lookup کردن. ولی توی دیتاستهای بزرگ، مثلا ۳۰ ملیون رکورد، عمق درخت باینری ما ۲۴ سطح خواهد بود در حالی که با branching factor 32 عمقش میشه ۴ سطح. مسلما سرچ کردن داخل این لیست درختی، خیلی سریعتر از نسخهی باینریش هست. مثل این هست که بخوایم توی یه باینری تری بگردیم که ۳۰تا عضو داره. بهش میگن almost instant lookup table (اونهم به خاطر اینه که در واقعیت instant وجود نداره و این تقریبا instant هست)
مسلما ریچ هیکی تصمیمات طراحی هوشمندانهی دیگه هم هم گرفته که من خبر ندارم ولی همین یکی توضیح میده که چطوری lookup کردن توی یه رکورد ۱۲ملیون تایی اینقدر سریع بوده و باعث شده به سرعت 30fps برسن.
چیزی که مسلمه اینه که جاوااسکریپت کلا توی ۱۰روز ساخته شده. سازندش اگه آدم فضایی هم بود نمیتونست چیز درستی از آب در بیاد. همینطور که میبینیم یکی از آشغالترین زبانهای برنامه نویسی ساخته شده توسط بشر هست و اگه اسمش شبیه زبان java نبود، شاید هیچوقت معروف نمیشد و ما زندگی زیباتری داشتیم.
یه کامیک باحال درمورد این موضوع
یه نکتهای رو هم اینجا بگم.
اینکه میگم بهتره مشکلات در سطح زبان برنامه نویسی حل بشن و نه در سطح لایبرری، دقیقا به خاطر همینه.
فایلهای پزشکی فرمتهای خاصی دارن. یعنی دستگاههای پزشکی به ما png (برای عکسهای دو بعدی) و obj (برای سه بعدی) نمیدن و گرچه داکیومنتهاشون خیلی کم و نایابه، برای اینکه یه نرمافزار بنویسیم تا فایلها رو باز کنه نیاز به نوشتن لایبرری داریم. یه لایبرری مثلا مخصوص فایلهای خروجی ماموگرافی. (داکیومنت فایلهای ماموگرافی رو نخوندم ولی با mri آشنایی دارم، بخشی از توضیحتم با توجه به چیزی هست که توی فایلهای mri هست)
فایلها دو مدل هستن. یا به صورت دوتا فایل کنار هم و یا به صورت یک فایل (که این دوتا به هم چسبیدن)
یکی از فایلها metadata هست. مثلا ۳۰۰بایت دیتا درمورد نوع نوشته شدن دیتا در فایل دوم و اینکه چند بعد داره و آیا زمان هم توش درنظر گرفته شده (مثلا آزمایش ۱۵دقیقه طول کشیده و تاثیر یک دارو یا یک محرک عصبی رو نشون میده روی بافت) و…
بعد از خوندن این فایل، تازه میفهمیم برای خوندن فایل دوم چطوری دیتاها رو تکه تکه جدا کنیم و بریزیم توی متغیرهای زبان برنامه نویسیمون.
فایل دوم اصولا به شکل ماتریس عددی هست. اعدادی که توی اون تاک نشون داده شد int 16 بودن (بین ۰ تا ۶۵۵۳۵) که فشردگی بافت (یا اطلاعات دیگه مثل حرارت اون نقطه) رو نشون میده. (دیتای دستگاههای mri معمولا ۵ بعدی هست. طول، عرض، ارتفاع، زمان، دما. ممکنه متغیرهای دیگهای هم داشته باشه)
مسلما مانیتور ما برای نمایش همچین چیزی ساخته نشده. مانیتورها میتونن رنگهای ۸بیتی رو نمایش بدن (بین ۰ تا ۲۵۵ و سه رنگ)
برای اینکه بتونیم یه int16 رو به int8 تبدیل کنیم، یا باید به روش ریاضی عمل کنیم (مثلا برای تبدیل ۶۵۲۴۴ از int16 به int8):
65244*255/65535 = 254
یا میتونیم باینری این عدد رو به تعداد ۸ بیت به سمت راست شیفت کنیم:
(65244)10 = (1111111011011100)2
(254)2 = (11111110)2
محاسبهی بالایی سختتره و البته باید نتیجه رو گرد کنیم (اعشار به دست میاد) ولی پایینی راحتتره و فقط بیتهای کم ارزش رو میندازیم دور.
حالا این عمل برای این بود که بخوایم کل تصویر رو روی مانیتور معمولی نمایش بدیم. (که نسبتا خیلی کار راحتیه)
حرکت اصلی زمانیه که بخوایم window leveling داشته باشیم.
توی window leveling چندتا کار انجام میشه که نوشتنش واقعا سخته و نیاز به این داره که روی یه نرمافزار به صورت ویدیویی اینکار رو انجام بدم و نتیجه (به همراه histogram) رو نشونتون بدم. پس فقط یکیشو میگم:
بعضیوقتها (زمانی که بخوان یه بافت که تراکمش خیلی کمتر یا بیشتر از میانگین هست رو با دقت ببینن) لازم میشه که فقط ۲۵۵تا مقدار دیده بشه و بقیهی مقادیر (مقادیری که بالاتر یا پایینتر هستن) نشون داده نشه.
به این صورت که مثلا اعداد ۰ تا ۲۵۵ به همون شکل که توی دیتای اصلی هستن نشون داده بشن و اعداد بالاتر تبدیل بشن به ۲۵۵ یا مثلا اعداد ۳۵۰ تا ۶۰۵ تبدیل بشن به ۰ تا ۲۵۵ و هرچی بالاتر هست تبدیل بشه به ۲۵۵ و هرچی پایینتر هست به ۰.
یه سری حالتهای دیگههم داره که هرچی فکر میکنم نمیتونم توی متن توضیح بدم.
یه سری ویرایشهای دیگه هم روی تصاویر انجام میشه. مثلا تغییر روشنایی و کنتراست، اعمال یه سری kernel روی تصاویر که اینها هم همشون ویرایش کردن تمام پیکسلها (یک لیست ۱۲ملیون تایی عدد) هستن.
کرنلهایی که استفاده میشه معمولا برای edge detect و sharpen هستن. یعنی کرنلهای 3x3 و 5x5 که وضعیت رنگ هر پیکسل رو با توجه به ۸ یا ۲۴ پیکسل اطرافش تغییر میده.
این پروژه کلا یه front-end هست که دکترها میان تصویر رو داخلش باز میکنن و تومور رو پیدا میکنن و علامت میزنن.
بعد تصویر به اضافهی محل اون علامتها توی دیتابیس ذخیره میشه. (کلا بک-اند کارش اینه که این دیتا رو ذخیره کنه. همین)
بعدا میان از این دیتا استفاده میکنن برای تعلیم neural network و دیتا رو میدن به کامپیوتر و میگن «این عکس تومور خوشخیم است» و «این عکس تومور بدخیم است»
و بقیهی ماجرای یادگیری ماشینی.
در نهایت احتمالا یه سیستمی ساخته میشه که هر بیماری میره پیش پزشک و ماموگرافی میکنه، اون تصویر فرستاده میشه به یه سرور و اون سرور میگه «این به احتمال ۹۳درصد خوشخیم است» و دیگه نیازی به نمونهبرداری نیست (نمونهبرداری طولانیه و دردناک. در بعضی مواقع خطرناک)
مشکل هم از اونجای شروع میشه که دکترها (انسانها) نمیتونن از روی ۴تا عکس تشخیص بدن یه تومور خوشخیم هست یا نه. چون تجربهی آنالیز چند ملیون تومور رو نداشتن. (ولی کامپیوتر به لطف این سیستم، تجربش رو داره)
چقدر زیاد نوشتم! کاش میتونستم توی زمان سفر کنم و این توضیحات رو یک سال پیش به خودم بدم.