VisTrails

معمارية تطبيقات المصادر المفتوحة (المجلد الأول)VisTrails

معمارية تطبيقات المصادر المفتوحة (المجلد الأول) VisTrails

Juliana Freire وDavid Koop وEmanuele Santos وCarlos Scheidegger وClaudio Silva وHuy T. Vo

إذا استمتعت بهذه الكتب، فقد يعجبك أيضًا التصميم البرمجي بالأمثلة في Python والتصميم البرمجي بالأمثلة في JavaScript.

VisTrails[1] نظام مفتوح المصدر يدعم استكشاف البيانات والتمثيل المرئي. وهو يضمّ السمات المفيدة في أنظمة سير العمل العلمي وأنظمة التمثيل المرئي، ويوسّعها إلى حدٍّ كبير. فمثل أنظمة سير العمل العلمي مثل Kepler وTaverna، يتيح VisTrails تحديد عمليات حسابية تدمج، وفقًا لمجموعة من القواعد، بين التطبيقات القائمة والموارد والمكتبات المرتبطة ارتباطًا ضعيفًا (loosely-coupled). ومثل أنظمة التمثيل المرئي مثل AVS وParaView، يجعل VisTrails تقنيات التمثيل العلمي والمعلوماتي المتقدّمة في متناول المستخدمين، فيتيح لهم استكشاف تمثيلاتٍ بصرية مختلفة لبياناتهم ومقارنتها. وبتيجة ذلك، يستطيع المستخدمون إنشاء سِيَر عمل معقّدة تجمع الخطوات المهمّة من الاكتشاف العلمي، من جمع البيانات ومعالجتها إلى التحليلات والتمثيلات البصرية المعقّدة، كلّها مدمجة في نظام واحد.

السمة التي تميّز VisTrails هي بنية تحتية المنشأ (provenance) التي يملكهاFSC+06. فـ VisTrails يلتقط ويحتفظ بسجل تفصيلي للخطوات التي اتُّبعت والبيانات التي اشتُقّت خلال مهمّة استكشافية ما. وقد استُخدمت سِيَر العمل تقليديًّا لأتمتة المهام المتكرّرة، لكن في التطبيقات ذات الطابع الاستكشافي، مثل تحليل البيانات والتمثيل المرئي، لا يتكرّر تقريبًا شيء—التغيّر هو القاعدة. فمع أن يولّد المستخدم الفرضيات عن بياناته ويقيّمها، تُنشأ سلسلة من سِيَر عمل مختلفة لكنها مترابطة، إذ يجري تعديلها تكراريًّا.

صُمِّم VisTrails لإدارة سِيَر العمل سريعة التطوّر هذه: فهو يحافظ على المنشأ الخاص بنواتج البيانات (مثل التمثيلات البصرية والمخططات)، وعلى المنشأ الخاص بسِيَر العمل التي اشتُقّت منها هذه النواتج، وعلى المنشأ الخاص بتنفيذاتها. ويوفّر النظام أيضًا إمكانات التعليق التوضيحي (annotation) ليتمكّن المستخدمون من إثراء المنشأ المُلتقط آليًّا.

إلى جانب تمكينه من إعادة إنتاج النتائج، يستثمر VisTrails معلومات المنشأ عبر سلسلة من العمليات وواجهات مستخدم بديهية تساعد المستخدمين على تحليل البيانات تعاونيًّا. ومن أبرز ما يدعمه النظام الاستدلال الانعكاسي (reflective reasoning) عن طريق تخزين النتائج المؤقتة، ما يتيح للمستخدمين فحص الإجراءات التي أدت إلى نتيجة والتفاعل مع سلاسل الاستدلال إلى الأمام وإلى الخلف. ويستطيع المستخدمون التنقّل بين إصدارات سير العمل بطريقة بديهية، والتراجع عن التغييرات دون فقدان النتائج، ومقارنة عدة سِيَر عمل بصريًا وعرض نتائجها جنبًا إلى جنب في جدول تمثيل بصري.

يعالج VisTrails مشكلات مهمّة في قابلية الاستخدام كانت قد أعاقت تبنّي أوسع لأنظمة سير العمل والتمثيل المرئي. ولخدمة مجموعة أوسع من المستخدمين، ومن بينهم كثيرون لا يملكون خبرة في البرمجة، يوفّر سلسلة من العمليات وواجهات المستخدم التي تبسّط تصميم سير العمل واستخدامه FSC+06، ومنها القدرة على إنشاء سِيَر العمل وتحسينها بالتناظر (analogy)، والاستعلام عن سِيَر العمل بالمثال، واقتراح استكمالات لسير العمل أثناء بناء المستخدمين لسِيَر العمل تفاعليًّا بواسطة نظام توصية SVK+07. كما طوّرنا إطارًا جديدًا يتيح إنشاء تطبيقات مخصّصة يمكن نشرها بسهولة أكبر للمستخدمين النهائيين (غير المخبرين).

تأتي قابلية توسيع VisTrails من بنية تحتية تتيح للمستخدمين دمج الأدوات والمكتبات بيساطة، وكذلك إنشاء نماذج أوّلية (prototypes) سريعة للوظائف الجديدة. وكان لذلك أثرٌ حاسم في تمكين استخدام النظام في مجموعة واسعة من مجالات التطبيقات، بما فيها العلوم البيئية، وطبّ النفس، وعلم الفلك، وعلم الكونيات، وفيزياء الطاقة العالية، والفيزياء الكمية، والنمذجة الجزيئية.

ولإبقاء النظام مفتوح المصدر ومتاحًا مجانًا للجميع، بنينا VisTrails مستخدمين حزمًا مجانية مفتوحة المصدر فحسب. وكُتب VisTrails بلغة Python ويستخدم Qt مجموعة أدوات الواجهة الرسومية الخاصة به (عبر روابط PyQt مع Python). ونظرًا لاتساع نطاق المستخدمين والتطبيقات، صمّمنا النظام منذ بدايته مع مراعاة قابلية النقل. ويعمل VisTrails على Windows وMac وLinux.

مكوّنات واجهة مستخدم VisTrails

الشكل 23.1: مكوّنات واجهة مستخدم VisTrails

23.1. نظرة عامة على النظام

استكشاف البيانات عملية إبداعية بطبيعتها، تتطلّب من المستخدمين تحديد البيانات ذات الصلة، ودمج هذه البيانات والتمثيل بها بصريًا، والتعاون مع الزملاء أثناء استكشاف حلول مختلفة، ونشر النتائج. ونظرًا لحجم البيانات وتعقيد التحليلات المعتادة في الاستكشاف العلمي، فإنّ هناك حاجة إلى أدوات تدعم الإبداع دعمًا أفضل.

هناك متطلّبان أساسيان لهذه الأدوات يأتيان جنبًا إلى جنب. أوّلًا، من المهمّ القدرة على تحديد عمليات الاستكشاف باستخدام أوصاف رسمية، ويُفضَّل أن تكون هذه الأوصاف قابلة للتنفيذ. ثانيًا، من أجل إعادة إنتاج نتائج هذه العمليات، وكذلك الاستدلال بشأن الخطوات المختلفة التي اتُّبعت لحل مسألة ما، يجب أن تمتلك هذه الأدوات القدرة على التقاط المنشأ بصورة منهجية. وقد صُمِّم VisTrails وهذه المتطلّبات في الحسبان.

23.1.1. سِيَر العمل والأنظمة القائمة على سِيَر العمل

تدعم أنظمة سير العمل إنشاء خطوط أنابيب المعالجة (سِيَر العمل) التي تدمج عدة أدوات. وبذلك تتيح أتمتة المهام المتكرّرة وإعادة إنتاج النتائج. وهي تحلّ بسرعة محلّ سكربتات الصدفة (shell) البدائية في مجموعة واسعة من المهام، كما يشهد به عدد من التطبيقات القائمة على سير العمل، سواء التجارية (مثل Mac OS X Automator من Apple وYahoo! Pipes) أو الأكاديمية (مثل NiPype وKepler وTaverna).

للسِيَر العمل مزايا عديدة مقارنة بالسكربتات والبرامج المكتوبة في اللغات عالية المستوى. فهي تقدّم نموذج برمجيًا بسيطًا تُبنى فيه سلسلة من المهام عبر وصل مخرجات مهمة بمدخلات مهمة أخرى. ويعرض الشكل 23.1 سير عمل يقرأ ملف CSV يحتوي على ملاحظات طقسية وينشئ مخططًا انتشاريًّا للقيم.

يسمح نموذج البرمجة الأبسط هذا لأنظمة سير العمل بأن تقدّم واجهات برمجة بصرية بديهية، ممّا يجعلها أكثر ملاءمة للمستخدمين الذين لا يملكون خبرة برمجية كبيرة. كما أنّ لسِيَر العمل بنية صريحة: إذ يمكن النظر إليها كرسوم بيانية، تمثّل فيها العُقد العمليات (أو الوحدات) مع معاملاتها، بينما تلتقط الحوافّ تدفّق البيانات بين العمليات. وفي مثال الشكل 23.1، تأخذ الوحدة CSVReader اسم ملف معاملًا لها (/weather/temp_precip.dat)، وتقرأ الملف، ثمّ تغذّي محتوياته الوحدتين GetTemperature وGetPrecipitation، اللتين ترسلان بدورهما قيم الحرارة والهطول إلى دالة في matplotlib تولّد مخططًا انتشاريًّا.

صُمِّمت معظم أنظمة سير العمل لمجال تطبيقي محدّد. فمثلًا، تستهدف Taverna سِيَر عمل في المعلوماتية الحيوية، ويتيح NiPype إنشاء سِيَر عمل في التصوير العصبي. وفي حين يدعم VisTrails قدرًا كبيرًا من الوظائف التي تقدّمها أنظمة سير العمل الأخرى، فقد صُمِّم لدعم المهمّات الاستكشافية العامة في مجموعة واسعة من المجالات، مع دمج عدّة أدوات ومكتبات وخدمات.

23.1.2. منشأ البيانات ومنشأ سير العمل

إنّ أهمية الاحتفاظ بمعلومات المنشأ للنتائج (ونواتج البيانات) مدركة على نطاق واسع في الأوساط العلمية. فمنشأ ناتج البيانات (المسمّى أيضًا سجل التدقيق، وسلسلة النسب، والنسق الوراثي) يتضمّن معلومات عن العملية والبيانات المستخدَمة في اشتقاق ناتج البيانات هذا. ويوفّر المنشأ توثيقًا مهمًّا يُعدّ مفتاحًا لحفظ البيانات، وتحديد جودتها ومؤلفيتها، وإعادة إنتاج النتائج والتحقّق منها FKSS08.

من مكوّنات المنشأ المهمّة معلومات عن السببية، أي وصف لعملية (سلسلة من الخطوات) أدت، إلى جانب بيانات الإدخال والمعاملات، إلى إنشاء ناتج بيانات. وعليه، فإنّ بنية المنشأ تحاكي بنية سير العمل (أو مجموعة سِيَر العمل) المستخدَم في اشتقاق مجموعة نتائج معيّنة.

وفي الواقع، فإنّ ما شكّل محفّزًا للانتشار الواسع لأنظمة سير العمل في العلوم هو إمكانية استخدامها بسهولة لالتقاط المنشأ آليًّا. فبينما جرى توسيع أنظمة سير العمل المبكّرة لتلتقط المنشأ، فقد صُمِّم VisTrails لدعم المنشأ منذ الأصل.

منشأ الاستكشاف المُثرى بالتعليقات التوضيحية

الشكل 23.2: منشأ الاستكشاف المُثرى بالتعليقات التوضيحية

23.1.3. واجهة المستخدم والوظائف الأساسية

يوضّح الشكل 23.1 والشكل 23.2 مكوّنات واجهة المستخدم المختلفة في النظام. ويقوم المستخدمون بإنشاء سِيَر العمل وتحريرها باستخدام محرِّر سير العمل (Workflow Editor).

لبناء رسوم سِيَر العمل البيانية، يمكن للمستخدمين سحب الوحدات من سجلّ الوحدات (Module Registry) وإفلاتها في مساحة محرِّر سير العمل. ويوفّر VisTrails سلسلة من الوحدات المدمجة، ويمكن للمستخدمين أيضًا إضافة وحداتهم الخاصة (للتفاصيل، انظر القسم 23.3). وعندما تُحدَّد وحدة ما، يعرض VisTrails معاملاتها (في منطقة تحرير المعاملات) حيث يمكن للمستخدم ضبط قيمها وتعديلها.

ومع تحسين مواصفة سير العمل، يلتقط النظام التغييرات ويعرضها للمستخدم في عرض شجرة الإصدارات الموصوف أدناه. ويمكن للمستخدمين التفاعل مع سِيَر العمل ونتائجها في جدول VisTrails. تمثّل كل خلية في الجدول عرضًا يقابل نسخة من سير عمل. وفي الشكل 23.1، تظهر نتائج سير العمل المعروض في محرِّر سير العمل في الخلية العلوية اليسرى من الجدول. ويمكن للمستخدمين تعديل معاملات سير العمل مباشرة، وكذلك مزامنة المعاملات عبر الخلايا المختلفة في الجدول.

يساعد عرض شجرة الإصدارات المستخدمين على التنقّل بين إصدارات سير العمل المختلفة. وكما يبيّن الشكل 23.2، فإنّ النقر على عقدة في شجرة الإصدارات يتيح للمستخدمين عرض سير عمل والنتيجة المرتبطة به (معاينة التمثيل المرئي) والبيانات الوصفية. تُلتقط بعض البيانات الوصفية آليًّا، مثل مُعرِّف المستخدم الذي أنشأ سير عمل معيّنًا وتاريخ الإنشاء، لكن يمكن للمستخدمين أيضًا تقديم بيانات وصفية إضافيّة، منها وسم يُعرِّف سير العمل ووصف مكتوب.

معمارية VisTrails

الشكل 23.3: معمارية VisTrails

23.2. تاريخ المشروع

كُتبت الإصدارات الأولى من VisTrails بلغتَي Java وC++ BCC+05. ووُزّع إصدار C++ على عدد قليل من أوائل المستخدِمين، وكان ملاحظاتهم أساسيًّا في تشكيل متطلّباتنا للنظام.

بعد أن لاحظنا اتجاهًا تصاعديًّا في تزايد عدد المكتبات والأدوات المبنيّة على Python في مجتمعات علمية متعدّدة، اخترنا Python أساسًا لـ VisTrails. إذ أصبح Python سريعًا لغةً رابطة عالمية حديثة للبرمجيات العلمية. فكثير من المكتبات المكتوبة بلغات مختلفة مثل Fortran وC وC++ تستخدم روابط Python وسيلةً لتوفير قدرات السكربتة. وبما أنّ VisTrails يهدف إلى تيسير تنسيق (orchestration) مكتبات برمجية متعدّدة في سِيَر العمل، فإنّ تنفيذًا خالصًا بـ Python يجعل ذلك أمرًا يسيرًا إلى حدٍّ كبير. وتحديدًا، توفّر Python ميزات تحميل الشيفرة ديناميكيًّا تشبه ما هو موجود في بيئات LISP، فيما تمتلك مجتمع مطوّرين أكبر بكثير ومكتبة قياسية ثريّة إلى حدٍّ استثنائي. وفي أواخر عام 2005، بدأنا تطوير النظام الحالي باستخدام Python/PyQt/Qt. وقد بسّط هذا الاختيار إلى حدٍّ كبير توسيع النظام، ولا سيما إضافة الوحدات والحزم الجديدة.

صدر أول إصدار تجريبي (beta) من نظام VisTrails في يناير 2007. ومنذ ذلك الحين، حُمِّل النظام أكثر من خمسة وعشرين ألف مرة.

23.3. داخل VisTrails

توضّح معمارية VisTrails عالية المستوى، المعروضة في الشكل 23.3، المكوّنات الداخلية التي تدعم وظائف واجهة المستخدم الموصوفة أعلاه. يتحكّم في تنفيذ سير العمل محرّك التنفيذ (Execution Engine)، الذي يتتبّع العمليات المستدعاة ومعاملاتها ويالتقط منشأ تنفيذ سير العمل (منشأ التنفيذ Execution Provenance). وكجزء من التنفيذ، يتيح VisTrails أيضًا التخزين المؤقت (caching) للنتائج الوسيطة في الذاكرة وعلى القرص. وكما نناقش في القسم 23.3، لا يُعاد تشغيل سوى تركيبات جديدة من الوحدات والمعاملات، وتُنفَّذ هذه باستدعاء الدوال الملائمة من المكتبات الأساسية (مثل matplotlib). وبعد ذلك يمكن تضمين نتائج سير العمل، المتّصلة بمنشئها، في المستندات الإلكترونية (القسم 23.4).

تُلتقط معلومات التغييرات في سِيَر العمل في شجرة إصدارات (Version Tree)، ويمكن تثبيتها باستخدام واجهات تخزين خلفية مختلفة، بما في ذلك مخزن ملفات XML في دليل محلي وقاعدة بيانات علائقية. ويوفّر VisTrails أيضًا محرّك استعلام يتيح للمستخدمين استكشاف معلومات المنشأ.

ونلاحظ أنّه، رغم أنّ VisTrails صُمِّم ليكون أداة تفاعلية، فإنّه يمكن أيضًا استخدامه في وضع الخادم. وبمجرد إنشاء سِيَر العمل، يمكن تنفيذها بواسطة خادم VisTrails. وهذه الميزة مفيدة في عدد من السيناريوهات، منها إنشاء واجهات قائمة على الويب تتيح للمستخدمين التفاعل مع سِيَر العمل، وإمكانية تشغيل سِيَر العمل في بيئات الحوسبة عالية الأداء.

23.3.1. شجرة الإصدارات: منشأ قائم على التغيير

نموذج المنشأ القائم على التغيير

الشكل 23.4: نموذج المنشأ القائم على التغيير

المفهوم الجديد الذي قدّمناه مع VisTrails هو فكرة منشأ تطوّر سير العمل FSC+06. فعلى عكس أنظمة سير العمل وأنظمة التمثيل المرئي القائمة على سير العمل السابقة، التي لا تحافظ إلّا على منشأ نواتج البيانات المشتقّة، يعامل VisTrails سِيَر العمل بوصفها عناصر بيانات من الدرجة الأولى، ويالتقط منشأها أيضًا. وإتاحة منشأ تطوّر سير العمل تدعم الاستدلال الانعكاسي. ويستطيع المستخدمون استكشاف عدّة سلاسل استدلال دون فقدان أي نتائج، ولأنّ النظام يخزّن النتائج الوسيطة، يستطيع المستخدمون الاستدلال حول هذه المعلومات واستخلاص استنتاجات منها. كما أنّها تتيح سلسلة من العمليات التي تبسّط العمليات الاستكشافية. فمثلًا، يستطيع المستخدمون التنقّل بسهولة في فضاء سِيَر العمل المُنشأة لمهمّة معيّنة، ومقارنتها بصريًا مع نتائجها (انظر الشكل 23.4)، واستكشاف فضاءات المعاملات (الكبيرة). وإلى جانب ذلك، يستطيع المستخدمون الاستعلام عن معلومات المنشأ والتعلّم بالمثال.

يُلتقط تطوّر سير العمل باستخدام نموذج المنشأ القائم على التغيير. وكما يوضّح الشكل 23.4، يخزّن VisTrails العمليات أو التغييرات المطبَّقة على سِيَر العمل (مثل إضافة وحدة، أو تعديل معامل، إلخ)، على نحو يشبه سجل معاملات قاعدة بيانات. وتُنمذج هذه المعلومات في شجرة، تقابل فيها كل عقدة إصدارًا من إصدارات سير العمل، بينما يمثّل الحافّ بين عقدة أمّ وعقدة ابنٍ التغيير المطبَّق على الأمّ للحصول على الابن. ونستخدم لفظَي شجرة الإصدارات وvistrail (اختصارًا لعبارة visual trail، أي "الأثر البصري") بالتبادل للإشارة إلى هذه الشجرة. ولاحظ أنّ النموذج القائم على التغيير يلتقط بصورة منتظمة تغييرات قيم المعاملات وتغييرات تعريفات سير العمل معًا. وهذه السلسلة من التغييرات كافية لتحديد منشأ نواتج البيانات، وهي تلتقط أيضًا معلومات عن كيفية تطوّر سير العمل عبر الزمن. والنموذج بسيط ومدمج في آنٍ واحد—فهو يستهلك مساحة أقلّ بكثير بديلًا عن تخزين إصدارات متعدّدة من سير العمل.

هناك عدد من الفوائد التي يأتي بها استخدام هذا النموذج. ويعرض الشكل 23.4 وظيفة الفروق البصرية التي يوفّرها VisTrails لمقارنة سيرَي عمل. ورغم أنّ سِيَر العمل ممثَّلة كرسوم بيانية، فإنّ استخدام النموذج القائم على التغيير يجعل مقارنة سيرَي عمل أمرًا بسيطًا جدًّا: يكفي التنقّل في شجرة الإصدارات وتحديد سلسلة الإجراءات اللازمة لتحويل سير العمل إلى الآخر.

ومن الفوائد المهمّة الأخرى للنموذج القائم على التغيير أنّ شجرة الإصدارات الكامنة يمكن أن تعمل كآلية لدعم التعاون. ولأنّ تصميم سِيَر العمل مهمّة صعبة مشهورة، فإنّه غالبًا ما يتطلّب تعاون عدّة مستخدمين.

يمكن التقاط معلومات المنشأ بسهولة أثناء تنفيذ سير العمل. وبعد اكتمال التنفيذ، من المهمّ أيضًا الحفاظ على روابط قوية بين ناتج البيانات ومنشئه، أي سير العمل والمعاملات وملفات الإدخال المستخدَمة في اشتقاق ناتج البيانات. وعندما تُنقل ملفات البيانات أو بيانات المنشأ أو تُعدَّل، قد يصعب العثور على البيانات المرتبطة بالمنشأ، أو العثور على المنشأ المرتبط بالبيانات. ويوفّر VisTrails آلية تخزين دائمة تدير ملفات بيانات الإدخال والبيانات الوسيطة وملفات بيانات الإخراج، فتُقوّي الروابط بين المنشأ والبيانات. وتقدّم هذه الآلية دعمًا أفضل لإعادة الإنتاج، إذ تضمن أنّ البيانات المشار إليها في معلومات المنشأ يمكن تحديد موقعها بسهولة (وبشكل صحيح). ومن الفوائد المهمّة الأخرى لهذه الإدارة أنّها تتيح التخزين المؤقت للبيانات الوسيطة، التي يمكن بعد ذلك مشاركتها مع مستخدمين آخرين.

23.3.2. تنفيذ سير العمل والتخزين المؤقت

صُمِّم محرّك التنفيذ في VisTrails ليسمح بدمج الأدوات والمكتبات الجديدة والقائمة. وحاولنا استيعاب الأساليب المختلفة المستخدَمة عادةً في تغليف برمجيات العرض المرئي والحساب العلمية التابعة لأطراف أخرى. وتحديدًا، يمكن دمج VisTrails مع مكتبات تطبيقات موجودة إمّا كثنائيات مصمَّفة مسبقًا تُنفَّذ في صدفة (shell) وتستخدم الملفات كمدخلات ومخرجات، وإمّا كمكتبات أصناف C++/Java/Python تمرّر كائنات داخلية كمدخلات ومخرجات.

يعتمد VisTrails نموذج تنفيذ قائم على تدفّق البيانات (dataflow)، حيث تنفّذ كل وحدة عملية حسابية واحدة، وتتدفّق البيانات التي تنتجها الوحدة عبر الروابط القائمة بين الوحدات. وتُنفَّذ الوحدات بأسلوب تصاعدي؛ إذ يُولَّد كل مُدخل عند الحاجة بتنفيذ تكراري للوحدات الواقعة قبلها في المسار (نقول عن الوحدة A إنّها سابقة لـ B متى وُجدت سلسلة من الروابط تمضي من A إلى B). وتُخزَّن البيانات الوسيطة مؤقتًا إمّا في الذاكرة (بوصفها كائن Python) وإمّا على القرص (مغلَّفةً بكائن Python يتضمّن معلومات عن الوصول إلى البيانات).

التمكين للمستخدمين من إضافة وظائفهم الخاصة إلى VisTrails، بنينا نظام حزم قابلًا للتوسيع (انظر القسم 23.3). وتتيح الحزم للمستخدمين تضمين وحداتهم الخاصة أو وحدات أطراف أخرى في سِيَر عمل VisTrails. وعلى مطوّر الحزمة أن يحدّد مجموعة من الوحدات الحسابية، وأن يحدّد لكل وحدة منافذ الإدخال والإخراج فضلًا عن تعريف العملية الحسابية. أمّا المكتبات القائمة فتحتاج طريقة compute إلى أن تحدّد الترجمة من منافذ الإدخال إلى معاملات الدالة القائمة، والربط من قيم النتائج إلى منافذ الإخراج.

في المهمّات الاستكشافية، كثيرًا ما تُنفَّذ سِيَر عمل متشابهة تتشارك في البنى الفرعية المشتركة واحدةً تلو الأخرى في زمن متقارب. ولتحسين كفاءة تنفيذ سير العمل، يخزّن VisTrails النتائج الوسيطة مؤقتًا للحدّ من إعادة الحساب. ولأنّنا نعيد استخدام نتائج تنفيذ سابقة، فإنّنا نفترض ضمنًا أنّ الوحدات القابلة للتخزين المؤقت صافية (pure)، أي أنّها تنتج المخرجات نفسها عند المدخلات نفسها. ويفرض هذا المتطلّب قيودًا سلوكية محدّدة على الأصناف، لكنّنا نعتقد أنّها قيود معقولة.

غير أنّ هناك حالات واضحة يتعذّر فيها بلوغ هذا السلوك. فمثلًا، الوحدة التي ترفع ملفًا إلى خادم بعيد أو تحفظ ملفًا على القرص لها أثر جانبي كبير فيما مخرجاتها أقلّ أهمية نسبيًّا. وقد تستخدم وحدات أخرى التعميم العشوائي، وقد يكون عدم الحتمية فيها مرغوبًا؛ ويمكن وسم هذه الوحدات بأنّها غير قابلة للتخزين المؤقت. لكنّ بعض الوحدات التي ليست صافية بطبيعتها يمكن تحويلها؛ إذ يمكن تغليف دالة تكتب البيانات في ملفّين لتُخرج محتويات الملفّين.

23.3.3. تسلسل البيانات وتخزينها

من المكوّنات الأساسية لأي نظام يدعم المنشأ تسلسل البيانات وتخزينها. كان VisTrails يخزّن البيانات في XML أصلًا عبر دالتَي fromXML وtoXML البسيطتين المضمّنتين في كائناته الداخلية (مثل شجرة الإصدارات، وكل وحدة). ولغ دعم تطوّر مخطّط (schema) هذه الكائنات، كانت هذه الدوال ترمّز أيضًا أي ترجمة بين إصدارات المخطّط. ومع تقدّم المشروع، نمت قاعدة مستخدمينا، فقرّرنا دعم تسلسلات مختلفة، بما فيها المخازن العلائقية. وإلى جانب ذلك، ومع تطوّر كائنات المخطّط، احتجنا إلى صيانة بنية تحتية أفضل لقضايا إدارة البيانات الشائعة مثل إدارة إصدارات المخطّط، والترجمة بين الإصدارات، ودعم العلاقات بين الكيانات. وقد فعلنا ذلك بإضافة طبقة قاعدة بيانات جديدة (db).

تتألف طبقة db من ثلاثة مكوّنات أساسية: كائنات المجال، ومنطق الخدمة، وطرق الاستمرارية. وتُصدَّر مكوّنات المجال والاستمرارية بإصداراتها بحيث يملك كل إصدار من المخطّط مجموعته الخاصة من الأصناف. وبهذه الطريقة نحتفظ بشيفرة تقرأ كل إصدار من المخطّط. وهناك أيضًا أصناف تعرّف الترجمات من كائنات في إصدار مخطّط إلى كائنات في إصدار آخر. وتوفّر أصناف الخدمة طرائق للتفاعل مع البيانات والتعامل مع كشف إصدارات المخطّط وترجمتها.

ولأنّ كتابة معظم هذه الشيفرة مملّة ومتكرّرة، نستخدم قوالب ومخطّطًا فوقيًّا (meta-schema) لتعريف تخطيط الكائنات (وأي فهارس في الذاكرة) وشيفرة التسلسل معًا. والمخطّط الفوقي مكتوب بـ XML، وهو قابل للتوسيع إذ يمكن إضافة تسلسلات غير التسلسل الافتراضي بـ XML والربط العلائقي الذي يعرّفه VisTrails. وهذا يشبه الربط بين الكائنات والعلاقات وأطرًا مثل Hibernate[2] وSQLObject[3]، لكنه يضيف بعض الإجراءات الخاصّة المؤتمتة لأمور مثل إعادة ربط المعرّفات وترجمة الكائنات من إصدار مخطّط إلى الإصدار التالي. وإلى جانب ذلك، يمكننا أيضًا استخدام المخطّط الفوقي نفسه لتوليد شيفرة تسلسل بلغات كثيرة. وبعد أن كتبنا في البداية «ميتا-Python»، حيث كان يُولَّد شيفرة المجال والاستمرارية بتشغيل شيفرة Python ومتغيّرات مأخوذة من المخطّط الفوقي، انتقلنا مؤخّرًا إلى قوالب Mako[4].

الترجمة التلقائية أمر محوري للمستخدمين الذين يحتاجون إلى ترحيل بياناتهم إلى إصدارات أحدث من النظام. ويضيف تصميمنا خطّافات (hooks) تجعل هذه الترجمة أقلّ إزعاجًا للمطوّرين بدرجة يسيرة. ولأنّنا نحتفظ بنسخة من الشيفرة لكل إصدار، لا تحتاج شيفرة الترجمة إلّا إلى ربط إصدار بآخر. وعلى المستوى الجذر، نعرّف خريطة تحدّد كيفية تحويل أي إصدار إلى أي إصدار آخر. وبالنسبة للإصدارات البعيدة، عادةً ما يستلزم ذلك سلسلة عبر عدّة إصدارات وسيطة. وفي البداية كانت هذه الخريطة تتّجه إلى الأمام فقط، ما يعني استحالة ترجمة الإصدارات الجديدة إلى الإصدارات القديمة، لكنّه أُضيفت ربطات عكسية لخرائط المخطّطات الأحدث.

يمتلك كل كائن طريقة update_version تأخذ إصدارًا مختلفًا من الكائن وتعيد الإصدار الحالي. وهي تقوم افتراضيًّا بترجمة تكرارية تُرقّى فيها كل كائن بربط حقول الكائن القديم بحقوله في الإصدار الجديد. ويفترض هذا الربط افتراضيًّا نسخ كل حقل إلى حقل يحمل الاسم نفسه، لكنّه من الممكن تعريف طريقة "تتجاوز" السلوك الافتراضي لأي حقل. والتجاوز هو طريقة تأخذ الكائن القديم وتعيد إصدارًا جديدًا. ولأنّ معظم تغييرات المخطّط لا تؤثّر إلّا في عدد قليل من الحقول، فإنّ الروابط الافتراضية تغطّي معظم الحالات، بينما تقدّم التجاوزات وسيلة مرنة لتعريف التغييرات الموضعية.

23.3.4. القابلية للتوسيع عبر الحزم وPython

كان النموذج الأوّلي الأول لـ VisTrails يملك مجموعة ثابتة من الوحدات. وقد كانت بيئة مثالية لتطوير الأفكار الأساسية حول شجرة إصدارات VisTrails والتخزين المؤقت لتنفيذات متعدّدة، لكنها حدّت من فائدته بعيدة المدى إلى حدٍّ كبير.

نرى في VisTrails بنيةً تحتية للعلوم الحسابية، وهذا يعني حرفيًّا أنّ النظام ينبغي أن يوفّر هياكل تسانيد تتيح تطوير أدوات وعمليات أخرى. ومتطلّب أساسي في هذا السيناريو هو القابلية للتوسيع. ومن الطرق المعتادة لتحقيق ذلك تحديد لغة هدف وكتابة مفسّر مناسب. وهذا أمر جذّاب لما يوفّره من تحكّم حميم في التنفيذ. ويتضاعف هذا الإغراء نظرًا لمتطلّباتنا في التخزين المؤقت. لكنّ تنفيذ لغة برمجة متكاملة جهد كبير لم يكن يومًا هدفنا الأوّلي. والأهمّ من ذلك أنّه كان خارج السؤال تمامًا أن نُلزم المستخدمين الذين يحاولون مجرّد استخدام VisTrails بتعلّم لغة جديدة تمامًا.

أردنا نظامًا يجعل من السهل على المستخدم إضافة وظائف مخصّصة. وفي الوقت نفسه، احتجنا إلى نظام قوي بما يكفي للتعبير عن قطع برمجية معقّدة نوعًا ما. فمثلًا، يدعم VisTrails مكتبة التمثيل المرئي VTK[5]. وتحتوي VTK على نحو 1000 صنف، تتغيّر بحسب الترجمة (compilation) والإعداد ونظام التشغيل. ولأنّ كتابة مسارات شيفرة مختلفة لكل هذه الحالات يبدو غير مجدٍ وغير مرجوّ في النهاية، قرّرنا أنّ من الضروري تحديد مجموعة وحدات VisTrails التي توفّرها أي حزمة معطاة ديناميكيًّا، فصارت VTK بطبيعيتها الهدف النموذجي لدينا لحزمة معقّدة.

كانت العلوم الحسابية أحد المجالات التي استهدفناها في الأصل، وفي الوقت الذي صمّمنا فيه النظام كان Python يكسب رواجًا بوصفه "شيفرة لصق" (glue code) بين هؤلاء العلماء. فبتحديد سلوك وحدات VisTrails المعرَّفة من المستخدم باستخدام Python نفسه، كنّا سنزيل إلى حدٍّ بعيد أكبر عائق أمام التبنّي. وقد تبيّن أنّ Python يوفّر بنيةً تحتية جيّدة للأصناف المعرَّفة ديناميكيًّا والانعكاس (reflection). فكل تعريف تقريبًا في Python له تكافؤ على هيئة تعبير من الدرجة الأولى. وخاصيتا الانعكاس المهمّتان في Python لنظام الحزم لدينا هما:

  • يمكن تعريف أصناف Python ديناميكيًّا عبر استدعاءات الكائن القابل للاستدعاء type. وتُعيد القيمة الناتجة تمثيلًا لصنف يمكن استخدامه بالطريقة نفسها تمامًا التي يُستخدم بها صنف Python المعرَّف اعتياديًّا.
  • يمكن استيراد وحدات Python عبر استدعاءات الدالة __import__، وتتصرّف القيمة الناتجة بالطريقة نفسها التي يتصرّف بها المُعرِّف في عبارة import الاعتيادية. ويمكن أيضًا تحديد المسار الذي تأتي منه هذه الوحدات في وقت التشغيل.

ولاستخدام Python هدفًا لدينا عيوب قليلة بالطبع. أوّلًا، تعني هذه الطبيعة الديناميكية لـ Python أنّه وإن كنا نودّ ضمان أمور مثل أمان الأنواع (type safety) في حِزم VisTrails، فإنّ ذلك غير ممكن عمومًا. والأهمّ أنّ بعض متطلّبات وحدات VisTrails، ولا سيما المتعلّقة بشفافية المراجع (referential transparency؛ بمزيد من التفصيل لاحقًا)، لا يمكن فرضها في Python. ومع ذلك، فإنّنا نعتقد أنّ من المفيد تقييد البنى المسموح بها في Python عبر آليات ثقافية، ومع هذا التحفّظ فإنّ Python لغة جذّابة إلى حدٍّ استثنائي لقابلية توسيع البرمجيات.

23.3.5. حِزم VisTrails والرزم

تغلّف حزمة VisTrails مجموعة من الوحدات. وأشيع تمثيل لها على القرص هو التمثيل نفسه المستخدَم لحزمة Python (في تصادم تسمية محتمل لسوء الحظ). وتتألف حزمة Python من مجموعة ملفات Python تعرّف قيم Python مثل الدوال والأصناف. أمّا حزمة VisTrails فهي حزمة Python تحترم واجهة معيّنة. ولديها ملفات تعرّف دوال ومتغيّرات محدّدة. وفي أبسط أشكالها، ينبغي أن تكون حزمة VisTrails دليلًا يحتوي ملفّين: __init__.py وinit.py.

الملف الأول __init__.py متطلّب في حِزم Python، ولا ينبغي أن يتضمّن إلّا عددًا قليلًا من التعريفات التي ينبغي أن تكون ثابتة. وإن كان لا سبيل إلى ضمان ذلك، فإنّ حِزم VisTrails التي تخالف هذا تُعدّ معطوبة. وتشمل القيم المعرَّفة في الملف مُعرِّفًا فريدًا عالميًّا (globally unique) للحزمة يُستخدَم للتمييز بين الوحدات عند تسلسل سِيَر العمل، وإصدارات الحزمة (وتصير إصدارات الحزمة مهمّة عند معالجة ترقيات سير العمل والحِزم، انظر القسم 23.4). ويمكن أن يتضمّن هذا الملف أيضًا دوالَّ اسمها package_dependencies وpackage_requirements. ولأنّنا نسمح لوحدات VisTrails بأن ترث من وحدات VisTrails أخرى إلى جانب الصنف الجذر Module، فإنّ من المعقول أن تمدّ حزمة VisTrails واحدة سلوك أخرى، وبذلك يجب تهيئة حزمة قبل أخرى. وتُحدَّد هذه التبعيات بين الحِزم بواسطة package_dependencies. أمّا الدالة package_requirements فتحدّد متطلّبات المكتبات على مستوى النظام، والتي قد يحاول VisTrails في بعض الحالات تلبيتها آليًّا من خلال تجريد الرزمة (bundle).

الرزمة (bundle) حزمة على مستوى النظام يديرها VisTrails عبر أدوات خاصة بكل نظام مثل RPM من RedHat أو APT من Ubuntu. وحين تتحقّق هذه الخصائص، يستطيع VisTrails تحديد خصائص الحزمة عبر استيراد وحدة Python مباشرةً والوصول إلى المتغيّرات المناسبة.

يتضمّن الملف الثاني init.py نقاط الدخول لجميع تعريفات وحدات VisTrails الفعلية. وأهمّ خاصية في هذا الملف هي تعريف دالتين، هما initialize وfinalize. وتُستدعى الدالة initialize عند تفعيل حزمة، بعد أن تكون كل الحِزم المعتمِدة قد فُعِّلت بدورها. وتؤدي مهامّ التهيئة لجميع الوحدات في الحزمة. أمّا الدالة finalize فتُستخدم عادةً لتحرير موارد وقت التشغيل (مثلًا يمكن تنظيف الملفات المؤقتة التي أنشأتها الحزمة).

يمثَّل كل وحدة من وحدات VisTrails في الحزمة بصنف Python واحد. ولتسجيل هذا الصنف في VisTrails، يستدعي مطوّر الحزمة الدالة add_module مرّة واحدة لكل وحدة من وحدات VisTrails. ويمكن أن تكون وحدات VisTrails هذه أصناف Python اعتباطية، لكن يتعيّن عليها احترام بضعة متطلّبات. وأوّلها أن يكون كل منها صنفًا مشتقًّا من صنف Python أساسيّ عرّفه VisTrails، اسمُه — على نحو مملّ ربّما — Module. ويمكن لوحدات VisTrails أن تستخدم الوراثة المتعددة، لكن ينبغي ألّا يكون سوى واحد من الأصناف وحدةً من VisTrails—لا يُسمح بسلاسل وراثة ماسية (diamond) في شجرة وحدات VisTrails. تصبح الوراثة المتعددة مفيدة على وجه الخصوص في تعريف مزيج الأصناف (class mix-ins): سلوكيات بسيطة ترمّزها أصناف أمّ يمكن تركيبها معًا لإنتاج سلوكيات أعقد.

تحدّد مجموعة المنافذ المتاحة واجهة وحدة VisTrails، وبذلك تؤثّر ليس في عرض هذه الوحدات فحسب بل أيضًا في ربطها بغيرها من الوحدات. ويجب، إذن، أن تُوصف هذه المنافذ وصفًا صريحًا للبنية التحتية لـ VisTrails. ويمكن ذلك إمّا بإجراء استدعاءات مناسبة إلى add_input_port وadd_output_port أثناء الاستدعاء إلى initialize، أو بتحديد القوائم _input_ports و_output_ports الخاصة بكل صنف لكل وحدة من وحدات VisTrails.

تحدّد كل وحدة العملية الحسابية التي يجري تنفيذها عبر تجاوز طريقة compute. وتنتقل البيانات بين الوحدات عبر المنافذ، ويُتّصل بها عبر الطريقتين get_input_from_port وset_result. وفي بيئات تدفّق البيانات التقليدية، يُحدَّد ترتيب التنفيذ عند الحاجة وفق طلبات البيانات. وفي حالتنا، يُحدَّد ترتيب التنفيذ عبر الفرز الطوبولوجي لوحدات سير العمل. وبما أنّ خوارزمية التخزين المؤقت تتطلّب رسمًا بيانيًّا غير دوريّ، فنحن نجدول التنفيذ بترتيب الفرز الطوبولوجي العكسي، حتى لا تؤدّي استدعاءات هذه الدوال إلى تشغيل الوحدات السابقة في المسار. وقد اتّخذنا هذا القرار عن قصد: فهو يجعل من الأسهل النظر في سلوك كل وحدة بمعزل عن سائر الوحدات، ممّا يجعل استراتيجية التخزين المؤقت لدينا أبسط وأكثر متانة.

وكدليل عام، ينبغي أن تمتع وحدات VisTrails عن استخدام دوال ذات آثار جانبية أثناء تقييم طريقة compute. وكما ناقشنا في القسم 23.3، فإنّ هذا المتطلّب يجعل التخزين المؤقت للتنفيذات الجزئية لسير العمل ممكنًا: فإذا احترمت وحدة هذه الخاصية، فإنّ سلوكها دالة لمخرجات الوحدات السابقة في المسار. وعندئذٍ لا يلزم حساب كل رسم فرعي غير دوري إلّا مرّة واحدة، ويمكن إعادة استخدام النتائج.

23.3.6. تمرير البيانات بوصفها وحدات

من السمات الغريبة في وحدات VisTrails وتواصلها أنّ البيانات التي تُمرَّر بين وحدات VisTrails هي بدورها وحدات من VisTrails. ففي VisTrails يوجد تسلسل واحد لأصناف الوحدات والبيانات. فمثلًا، يمكن للوحدة أن تقدّم نفسها كمخرج لعملية حسابية (وفي الواقع، تقدّم كل وحدة منفذ إخراج افتراضيًّا باسم "self"). والعيب الرئيسي هو فقدان الفصل المفاهيمي بين الحساب والبيانات الذي يُرى أحيانًا في المعماريات القائمة على تدفّق البيانات. لكنّ هناك ميزتين كبيرتين. الأولى أنّ هذا يحاكي عن قرب أنظمة أنواع الكائنات في Java وC++، ولم يكن هذا الاختيار عشوائيًّا: فدعم التغليف التلقائي لمكتبات الأصناف الكبيرة مثل VTK كان مهمًّا جدًّا بالنسبة إلينا. وتتيح هذه المكتبات للكائنات أن تنتج كائنات أخرى كنتائج حسابية، ما يجعل التغليف الذي يميّز بين الحساب والبيانات أعقد.

أمّا الميزة الثانية التي يجلبها هذا القرار، فهي أنّ تعريف القيم الثابتة والمعاملات التي يضبطها المستخدم في سِيَر العمل يصبح أسهل وأكثر اندماجًا باتساق مع بقية النظام. خُذ مثلًا سير عمل يحمّل ملفًا من موقع على الويب محدَّد بقيمة ثابتة. وهذا محدَّد حاليًّا عبر واجهة رسومية يمكن فيها تعيين عنوان URL معاملًا (انظر منطقة تحرير المعاملات في الشكل 23.1). ويكمن التعديل الطبيعي لهذا السير العمل في استخدامه لجلب عنوان URL محسوب في موضع سابق له في المسار. ونودّ ألّا يتغيّر بقية سير العمل إلّا بأقلّ قدر ممكن. وبافتراض أنّ الوحدات تستطيع إخراج نفسها، يمكننا ببساطة وصل سلسلة نصّية تحمل القيمة الصحيحة بالمنفذ المقابل للمعامل. ولأنّ مخرج الثابت يُقيَّم إلى ذاته، فإنّ السلوك مطابق تمامًا كما لو كانت القيمة قد حُدِّدت فعلًا كقيمة ثابتة.

النمذجة الأولية لوظائف جديدة بوحدة PythonSource

الشكل 23.5: النمذجة الأولية لوظائف جديدة بوحدة PythonSource

هناك اعتبارات أخرى متضمّنة في تصميم الثوابت. فلكل نوع من الثوابت واجهة رسومية مثلى مختلفة لتعيين القيم. فمثلًا، في VisTrails توفّر وحدة ثابت ملفّ حوارًا لاختيار الملف؛ وتُعيَّن القيمة المنطقية عبر مربع اختيار؛ ولقيمة اللون منتقي ألوان أصيل لكل نظام تشغيل. ولتحقيق هذا التعميم، يتعيّن على المطوّر أن يشتقّ ثابتًا مخصّصًا من الصنف الأساس Constant ويقدّم تجاوزات تعرّف عنصر واجهة رسومية مناسبًا وتمثيلًا نصّيًّا (بحيث يمكن تسلسل الثوابت الاعتباطية إلى القرص).

ونلاحظ أنّه، بالنسبة لمهمّات النمذجة الأولية البسيطة، يوفّر VisTrails وحدة مدمجة اسمها PythonSource. ويمكن استخدام وحدة PythonSource لإدراج سكربتات مباشرةً في سير عمل. وتتيح نافذة الإعداد لوحدة PythonSource (انظر الشكل 23.5) تحديد منافذ إدخال وإخراج متعدّدة إلى جانب شيفرة Python المطلوب تنفيذها.

23.4. المكوّنات والميزات

وكما ناقشنا أعلاه، يوفّر VisTrails مجموعة من الوظائف وواجهات المستخدم التي تبسّط إنشاء المهمّات الحسابية الاستكشافية وتنفيذها. وفيما يلي، نصف بعضها. كما نناقش بإيجاز كيف يجري استخدام VisTrails أساسًا لبنية تحتية تدعم إنشاء منشورات غنية بالمنشأ. ولمزيد من الوصف الشامل لـ VisTrails وميزاته، راجع التوثيق الإلكتروني لـ VisTrails[6].

جدول التمثيل المرئي

الشكل 23.6: جدول التمثيل المرئي

23.4.1. جدول التمثيل المرئي

يتيح VisTrails للمستخدمين استكشاف نتائج سِيَر عمل متعدّدة ومقارنتها باستخدام جدول التمثيل المرئي (انظر الشكل 23.6). وهذا الجدول حزمة VisTrails لها واجهتها الخاصة المكوّنة من أوراق وخلايا. وتتضمّن كل ورقة مجموعة من الخلايا، ذات تخطيط قابل للتخصيص. وتحتوي الخلية على التمثيل البصري لنتيجة أنتجها سير عمل، ويمكن تخصيصها لعرض أنواع متفرّقة من البيانات.

لعرض خلية في الجدول، يجب أن يحتوي سير العمل على وحدة مشتقّة من الوحدة الأساس SpreadsheetCell. وتقابل كل وحدة SpreadsheetCell خلية واحدة في الجدول، لذا يمكن لسير عمل واحد أن يولّد خلايا متعدّدة. وتتكفّل طريقة compute في الوحدة SpreadsheetCell بالتواصل بين محرّك التنفيذ (الشكل 23.3) والجدول. وأثناء التنفيذ، ينشئ الجدول خلية بحسب نوعها عند الحاجة، مستغلًّا إنشاء الأصناف الديناميكي في Python. وبذلك يمكن تحصيل تمثيلات بصرية مخصّصة عبر إنشاء صنف مشتقّ من SpreadsheetCell وجعل طريقة compute فيه ترسل نوع خلية مخصّصًا إلى الجدول. فمثلًا، في سير العمل المبيّن في الشكل 23.1، يكون MplFigureCell وحدةً من نوع SpreadsheetCell مصمَّمة لعرض الصور التي ينتجها matplotlib.

ولأنّ الجدول يستخدم PyQt واجهةً خلفيةً لواجهته الرسومية، يجب أن ترث عناصر واجهة الخلية المخصّصة من QWidget في PyQt. ويجب أن تعرّف أيضًا طريقة updateContents، التي يستدعيها الجدول لتحديث العنصر عند وصول بيانات جديدة. وقد تعرّف كل عنصر واجهة خلية شريط أدوات مخصّصًا اختياريًّا عبر تنفيذ طريقة toolbar؛ وسيُعرض في منطقة شريط أدوات الجدول عند تحديد الخلية.

يعرض الشكل 23.6 الجدول حين تُحدَّد خلية من نوع VTK، وفي هذه الحالة يوفّر شريط الأدوات عناصر محدّدة لتصدير صور PDF، وحفظ مواضع الكاميرا في سير العمل، وإنشاء الحركات (animations). وتعرّف حزمة الجدول عنصر QCellWidget قابلًا للتخصيص، ويوفّر ميزات مشتركة مثل إعادة تشغيل السجل (الأنيميشن) وتمرير أحداث اللمس المتعدد. ويمكن استخدام هذا العنصر بدلًا من QWidget لتسريع تطوير أنواع الخلايا الجديدة.

ورغم أنّ الجدول يقبل عناصر واجهة من PyQt بوصفها أنواعًا للخلايا فحسب، فإنّ من الممكن دمج عناصر واجهة مكتوبة بمجموعات أدوات رسومية أخرى. وللقيام بذلك، يجب أن يصدّر العنصر عناصره إلى المنصّة الأصليّة، ثم يمكن استخدام PyQt لالتقاطه. ونستخدم هذا الأسلوب مع عنصر الواجهة VTKCell لأنّ العنصر الفعلي مكتوب بـ C++. وفي وقت التشغيل، يلتقط VTKCell مُعرِّف النافذة، أي مقبض Win32 أو X11 أو Cocoa/Carbon بحسب النظام، ثمّ يربطه بمساحة الجدول.

وكما الخلايا، يمكن تخصيص الأوراق أيضًا. افتراضيًّا، تعيش كل ورقة في عرض بتبويبات ولها تخطيط جدولي. لكنّه يمكن فصل أي ورقة من نافذة الجدول، ما يسمح بإظهار عدّة أوراق في الوقت نفسه. ومن الممكن أيضًا إنشاء تخطيط أوراق مختلف عبر الاشتقاق من StandardWidgetSheet، وهو عنصر واجهة من PyQt أيضًا. ويتولى StandardWidgetSheet إدارة تخطيطات الخلايا، وكذلك التفاعلات مع الجدول في وضع التحرير. وفي وضع التحرير، يستطيع المستخدمون التلاعب بتخطيط الخلايا وتنفيذ إجراءات متقدّمة على الخلايا بدلًا من التفاعل مع محتويات الخلايا. وتشمل هذه الإجراءات تطبيق التناظرات (انظر القسم 23.4) وإنشاء إصدارات جديدة من سير العمل من استكشافات المعاملات.

23.4.2. الفروق البصرية والتناظرات

أثناء تصميمنا لـ VisTrails، أردنا تمكين استخدام معلومات المنشأ إلى جانب التقاطها. أوّلًا، أردنا أن يرى المستخدمون الفروق الدقيقة بين الإصدارات، لكنّنا أدركنا لاحقًا أنّ الميزة الأكثر نفعًا هي القدرة على تطبيق هذه الفروق على سِيَر عمل أخرى. وكلتا المهمّتين ممكنتان لأنّ VisTrails يتتبّع تطوّر سِيَر العمل.

ولأنّ شجرة الإصدارات تلتقط جميع التغييرات وبإمكاننا عكس كل إجراء، يمكننا إيجاد سلسلة كاملة من الإجراءات تحوّل إصدارًا إلى آخر. ولاحظ أنّ بعض التغييرات يلغي بعضها بعضًا، ممّا يجعل من الممكن ضغط هذه السلسلة. فمثلًا، لا يلزم فحص إضافة وحدة حُذفت لاحقًا عند حساب الفرق. وأخيرًا، لدينا بعض الاستدلالات التجريبية (heuristics) لتبسيط السلسلة أكثر: فحين تظهر الوحدة نفسها في سيرَي العمل لكن أُضيفت عبر إجراءين منفصلين، فإنّنا نلغي الإضافات والحذفَين.

من مجموعة التغييرات، يمكننا إنشاء تمثيل بصري يُظهر الوحدات والوصلات والمعاملات المتشابهة والمختلفة. ويوضّح ذلك الشكل 23.4. فالوحدات والوصلات التي تظهر في سيرَي العمل معًا تُلوَّن بالرمادي، وتلك التي تظهر في أحدهما فقط تُلوَّن وفق سير العمل الذي تظهر فيه. أمّا الوحدات المتطابقة ذات المعاملات المختلفة فتُظلَّل بدرجة أفتح من الرمادي، ويستطيع المستخدم فحص فروق المعاملات لوحدة بعينها في جدول يعرض القيم في كل سير عمل.

تتيح عملية التناظر للمستخدمين أخذ هذه الفروق وتطبيقها على سِيَر عمل أخرى. فإذا كان المستخدم قد أجرى مجموعة تغييرات على سير عمل قائم (مثل تغيير دقّة صورة الإخراج وصيغة ملفّها)، فيمكنه تطبيق التغييرات نفسها على سِيَر عمل أخرى عبر تناظر. وللقيام بذلك، يختار المستخدم سير عمل مصدر وسير عمل هدف، يحدّدان مجموعة التغييرات المرغوبة، فضلًا عن سير العمل الذي يرغب في تطبيق التناظر إليه. يحسب VisTrails الفرق بين سيرَي العمل الأوّلين بوصفه قالبًا، ثمّ يحدّد كيفية إعادة ربط هذا الفرق بقصد تطبيقه على سير العمل الثالث. ولأنّه من الممكن تطبيق الفروق على سِيَر عمل لا تطابق سير العمل الابتدائي تمامًا، فنحن بحاجة إلى مطابقة لينة (soft matching) تسمح بترابطات بين الوحدات المتشابهة. وبهذه المطابقة، يمكننا إعادة ربط الفرق بحيث يمكن تطبيق سلسلة التغييرات على سير العمل المختار SVK+07. وهذه الطريقة ليست مضمونة الصواب وقد تولّد سِيَر عمل جديدة لا تطابق تمامًا ما كان مرغوبًا. وفي هذه الحالات، قد يحاول المستخدم تصحيح أي أخطاء أدخلتها، أو العودة إلى الإصدار السابق وتطبيق التغييرات يدويًّا.

لحساب المطابقة اللينة المستخدَمة في التناظرات، نريد أن نوازن بين المطابقات المحلية (وحدات متطابقة أو شديدة التشابه) وبين بنية سير العمل الإجمالية. ولاحظ أنّ حساب المطابقة المتطابقة نفسها غير فعّال بسبب صعوبة تشابه الرسوم الفرعية (subgraph isomorphism)، فنحتاج إلى استدلال تجريبي. وباختصار، إذا كان في سيرَي العمل وحدتان متشابهتان إلى حدٍّ ما يتشاركان جيران متشابهين، فقد نستنتج أنّ هاتين الوحدتين تؤدّيان وظيفة متشابهة وينبغي مطابقتهما أيضًا. وبصيغة أكثر رسميّة، نبني رسمًا بيانيًّا حاصلًا (product graph) تكون فيه كل عقدة زوجًا محتملًا من وحدات سيرَي العمل الأصليَّين، ويشير الحافّ إلى وصلات مشتركة. ثمّ ننفّذ خطوات تنشر درجات كل عقدة عبر الحوافّ إلى العُقد المجاورة. وهذه عملية ماركوفية شبيهة بـ PageRank من Google، وستتقارب في النهاية تاركةً مجموعة درجات صارت تضمّ بعض المعلومات العامة. ومن هذه الدرجات يمكننا تحديد أفضل مطابقة، مستخدمين عتبةً تترك الوحدات شديدة الاختلاف بلا زوج.

23.4.3. الاستعلام عن المنشأ

يشمل المنشأ الذي يلتقطه VisTrails مجموعة من سِيَر العمل، لكل منها بنيته وبياناته الوصفية وسجلّات تنفيذه الخاصة. ومن المهمّ أن يستطيع المستخدمون الوصول إلى هذه البيانات واستكشافها. ويوفّر VisTrails واجهتي استعلام: واحدة نصّية وأخرى بصرية (WYSIWYG). فبالنسبة لمعلومات مثل الوسوم والتعليقات التوضيحية والتواريخ، يمكن للمستخدم استخدام بحث بالكلمات المفتاحية مع ترميز اختياري. فمثلًا: ابحث عن كل سِيَر العمل التي تحمل الكلمة المفتاحية plot والتي أنشأها user:~dakoop. لكنّ الاستعلام عن رسوم فرعية بعينها من سير العمل يُعبَّر عنه بسهولة أكبر عبر واجهة بصرية للاستعلام بالمثال، حيث يمكن للمستخدمين إمّا بناء الاستعلام من الصفر أو نسخ جزء قائم من خط أنابيب المعالجة وتعديله.

عند تصميم واجهة الاستعلام بالمثال هذه، احتفظنا بمعظم شيفرة محرِّر سير العمل القائم، مع بعض التغييرات في بناء المعاملات. فبالنسبة إلى المعاملات، من المفيد غالبًا البحث عن مجالات أو كلمات مفتاحية بدلًا من القيم الدقيقة. وعليه، أضفنا مُعدِّلات إلى حقول قيم المعاملات؛ فحين يضيف المستخدم قيمة معامل أو يحرّرها، يمكنه اختيار أحد هذه المعدِّلات التي تفترض المطابقة الدقيقة افتراضيًّا. وإلى جانب بناء الاستعلام بصريًّا، تُعرض نتائج الاستعلام بصريًّا أيضًا. فتُظلَّل الإصدارات المطابقة في شجرة الإصدارات، ويُعرض أي سير عمل مختار مع تظليل الجزء المطابق. ويستطيع المستخدم الخروج من وضع نتائج الاستعلام ببدء استعلام آخر أو بالنقر على زر إعادة الضبط.

23.4.4. البيانات الدائمة

يحفظ VisTrails منشأ كيفية اشتقاق النتائج، ومواصفة كل خطوة. لكنّ إعادة إنتاج تشغيل سير عمل قد تكون صعبة إذا لم تعد البيانات التي يحتاجها سير العمل متاحة. وإلى جانب ذلك، في سِيَر العمل طويلة التشغيل، قد يكون من المفيد تخزين البيانات الوسيطة بوصفها ذاكرة تخزين مؤقت دائمة ممتدّة عبر الجلسات، تفاديًا لإعادة الحساب.

تخزن أنظمة سير العمل كثيرة مسارات نظام الملفات إلى البيانات بوصفها منشأً، لكنّ هذا الأسلوب يعترضه مشاكل. فقد يُعيد مستخدم تسمية ملف، أو ينقل سير العمل إلى نظام آخر دون نسخ البيانات، أو يغيّر محتويات البيانات. وفي أيّ من هذه الحالات لا يكفي تخزين المسار بوصفه منشأً. أمّا تجزئة البيانات وتخزين التجزئة بوصفها منشأً فيساعد على تحديد ما إذا كانت البيانات قد تغيّرت، لكنه لا يساعد في تحديد موقع البيانات إن كانت موجودة. ولمعالجة هذه المشكلة، أنشأنا حزمة الاستمرارية (Persistence Package)، وهي حزمة VisTrails تستخدم بنية التحكّم بالإصدارات لتخزين بيانات يمكن الإشارة إليها من المنشأ. ونستخدم حاليًّا Git لإدارة البيانات، وإن كان من الممكن بسهولة استخدام أنظمة أخرى.

نستخدم المعرّفات الفريدة عالميًّا (universally unique identifiers، أو UUIDs) لتعريف البيانات، وبصمات التزام (commit hashes) من git للإشارة إلى الإصدارات. وإذا تغيّرت البيانات من تشغيل إلى آخر، فتُودَع نسخة جديدة في المستودع. وعليه، فإنّ الزوج (uuid, version) مُعرِّف مركَّب لاسترجاع البيانات في أيّ حالة. وإلى جانب ذلك، نخزّن تجزئة البيانات فضلًا عن بصمة الجزء السابق في المسار من سير العمل الذي أنشأها (إذا لم تكن مُدخلًا). وهذا يتيح الربط بين بيانات قد تُعرَّف بصورة مختلفة، فضلًا عن إعادة استخدام البيانات حين يُشغَّل الحساب نفسه مجدّدًا.

كان الشاغل الرئيسي عند تصميم هذه الحزمة هو الطريقة التي يتمكّن بها المستخدمون من اختيار بياناتهم واسترجاعها. كما رغبنا في الإبقاء على جميع البيانات في المستودع نفسه، بغضّ النظر عن استخدامها بوصفها بيانات إدخال أو إخراج أو بيانات وسيطة (فقد يُستخدم إخراج سير عمل بوصفه مُدخلًا لسير آخر). وهناك وضعان رئيسيان قد يلجأ إليهما المستخدم لتعريف البيانات: إنشاء مرجع جديد، أو استخدام مرجع قائم. ولاحظ أنّه بعد التنفيذ الأول سيصبح المرجع الجديد مرجعًا قائمًا لأنّه ثُبِّت أثناء التنفيذ؛ وقد يختار المستخدم لاحقًا إنشاء مرجع آخر إن رغب، لكنّ هذه حالة نادرة. ولأنّ المستخدم كثيرًا ما يرغب في استخدام أحدث إصدار من البيانات، فإنّ المرجع المحدَّد دون إصدار بعينه سيأخذ أحدث إصدار افتراضيًّا.

تذكّر أنّنا قبل تنفيذ وحدة ما نحدّث جميع مُدخلاتها تنفيذًا تكراريًّا. ولن تحدّث وحدة البيانات الدائمة مُدخلاتها إذا كانت الحسابات السابقة في المسار قد نُفِّذت مسبقًا. ولتحديد ذلك، نقارن بصمة سير العمل الفرعي السابق في المسار بالمستودع الدائم، ونسترجع البيانات المحسوبة مسبقًا إن وُجدت هذه البصمة. وإلى جانب ذلك، نسجّل معرّفات البيانات وإصداراتها بوصفها منشأً، بحيث يمكن إعادة إنتاج تنفيذ بعينه.

23.4.5. الترقيات

ولأنّ المنشأ في جوهر VisTrails، فإنّ القدرة على ترقية سِيَر العمل القديمة كي تعمل مع إصدارات أحدث من الحِزم مسألة محورية. ولأنّ الحِزم يمكن أن تُنشئها أطراف أخرى، فنحن بحاجة إلى البنية التحتية لترقية سِيَر العمل، وإلى الخطّافات التي تمكّن مطوّري الحِزم من تحديد مسارات الترقية. والإجراء الأساسي في ترقية سير العمل هو استبدال وحدة بإصدار جديد منها. ولاحظ أنّ هذا الإجراء معقّد لأنّنا علينا استبدال جميع الوصلات والمعاملات التابعة للوحدة القديمة. وإلى جانب ذلك، قد تحتاج الترقيات إلى إعادة ضبط معاملات الوحدة أو وصلاتها أو إعادة إسنادها أو تسميتها، مثلًا عند تغيّر واجهة الوحدة.

تُوسَم كل حزمة (مع وحداتها المرتبطة) بإصدار، وإذا تغيّر هذا الإصدار فإنّنا نفترض أنّ وحدات تلك الحزمة ربّما تغيّرت. ولاحظ أنّ بعضها، بل معظمها، قد لا يكون قد تغيّر، لكن دون إجراء تحليل للشيفرة بأنفسنا لا يمكننا التحقق من ذلك. ومع ذلك، نحاول تلقائيًّا ترقية أي وحدة لم تتغيّر واجهتها. وللقيام بذلك، نحاول استبدال الوحدة بالإصدار الجديد ونُطلق استثناءً إن لم ينجح الأمر. وحين يكون المطوّرون قد غيّروا واجهة وحدة أو أعادوا تسمية وحدة، نتيح لهم تحديد هذه التغييرات صراحةً. ولجعل ذلك أكثر قابلية للإدارة، أنشأنا طريقة remap_module تتيح للمطوّرين تحديد المواضع التي يلزم فيها تعديل سلوك الترقية الافتراضي فحسب. فمثلًا، يستطيع المطوّر الذي أعاد تسمية مُدخل file' إلى value' أن يحدّد هذا الربط تحديدًا بحيث، عند إنشاء الوحدة الجديدة، تصبح أي وصلات بـ file' في الوحدة القديمة متّصلة بـ value'. وفيما يلي مثال على مسار ترقية لوحدة مدمجة في VisTrails:

def handle_module_upgrade_request(controller, module_id, pipeline):
   module_remap = {'GetItemsFromDirectory':
                       [(None, '1.6', 'Directory',
                         {'dst_port_remap':
                              {'dir': 'value'},
                          'src_port_remap':
                              {'itemlist': 'itemList'},
                          })],
                   }
  return UpgradeWorkflowHandler.remap_module(controller, module_id, pipeline,
                                             module_remap)

ترقّي هذه القطعة من الشيفرة سِيَر العمل التي تستخدم الوحدة القديمة GetItemsFromDirectory (أي إصدار حتى 1.6) لتستخدم وحدة Directory بدلًا منها. وهي تربط منفذ dir من الوحدة القديمة بـ value، وتربط منفذ itemlist بـ itemList.

تنشئ أي ترقية إصدارًا جديدًا في شجرة الإصدارات، بحيث يمكن التمييز بين التنفيذات التي تسبق الترقيات وتليها ومقارنتها. ومن الممكن أن تغيّر الترقيات تنفيذ سير العمل (مثلًا إذا أصلح مطوّر حزمة خطأً ما)، ونحتاج إلى تتبّع ذلك بوصفه معلومات منشأ. ولاحظ أنّه في الإصدارات الأقدم من vistrails قد يلزم ترقية كل إصدار في الشجرة. ولتقليل الفوضى، نرقّي الإصدارات التي انتقل إليها المستخدم فحسب. وإلى جانب ذلك، نوفّر تفضيلًا يتيح للمستخدم تأجيل تثبيت أي ترقية حتى يُعدَّل سير العمل أو يُنفَّذ؛ فإذا اكتفى المستخدم بعرض ذلك الإصدار، فلا حاجة إلى تثبيت الترقية.

23.4.6. مشاركة النتائج الغنية بالمنشأ ونشرها

وفيما كانت إعادة الإنتاج هي حجر الأساس في المنهج العلمي، فإنّ المنشورات الحالية التي تصف تجارب حسابية كثيرًا ما تفشل في توفير معلومات كافية تجعل النتائج قابلة للتكرار أو للتعميم. ومؤخّرًا، تجدّد الاهتمام بنشر النتائج القابلة لإعادة الإنتاج. ومن العوائق الرئيسية أمام تبنّي هذه الممارسة على نطاق أوسع أنّ من الصعب إنشاء رزمة تضمّ جميع المكوّنات (مثل البيانات والشيفرة وإعدادات المعاملات) اللازمة لإعادة إنتاج نتيجة، فضلًا عن التحقّق من تلك النتيجة.

وبالتقاط منشأ تفصيلي، وفضلًا للميزات الكثيرة الموصوفة أعلاه، يبسّط VisTrails هذه العملية في التجارب الحسابية التي تُنفَّذ داخل النظام. لكنّ هناك حاجة إلى آليّات تربط المستندات بمعلومات المنشأ وتشاركها في آنٍ واحد.

طوّرنا حِزم VisTrails التي تتيح ربط النتائج الواردة في الأوراق العلمية بمنشئها، كأنها تعليق عميق (deep caption). وباستخدام حزمة LaTeX التي طوّرناها، يستطيع المستخدمون إدراج أشكال مرتبطة بسِيَر عمل في VisTrails. وسيقوم شيفرة LaTeX التالية بتوليد شكل يحتوي على نتيجة سير عمل:

\begin{figure}[t]
{
\vistrail[wfid=119,buildalways=false]{width=0.9\linewidth}
}
\caption{Visualizing a binary star system simulation. This is an image
  that was generated by embedding a workflow directly in the text.}
<span class="content-anchor" id="fig:astrophysics"></span>
\end{figure}

وحين تُترجَم المستند باستخدام pdflatex، فإنّ الأمر \vistrail سيستدعي سكربت Python بالمعاملات الواردة، وهو سكربت يرسل رسالة XML-RPC إلى خادم VisTrails لتنفيذ سير العمل ذي id 119. ويحمّل سكربت Python هذا النتائج نفسها من الخادم ويضمّها في مستند PDF الناتج عبر توليد أوامر LaTeX من نوع \includegraphics مربوطة بروابط فائقة، باستخدام خيارات التخطيط المحدّدة (width=0.9\linewidth).

ومن الممكن أيضًا تضمين نتائج VisTrails في صفحات الويب والويكي ومستندات Word وعروض PowerPoint. وقد تمّ الربط بين Microsoft PowerPoint وVisTrails عبر نموذج كائن المكوّنات (Component Object Model، أو COM) وواجهة الربط والتضمين الكائني (Object Linking and Embedding، أو OLE). ولكي يتفاعل كائن مع PowerPoint، لا بدّ من تنفيذ واجهات IOleObject وIDataObject وIPersistStorage في COM على الأقلّ. وبما أنّنا نستخدم صنف QAxAggregated في Qt، وهو تجريد لتنفيذ واجهات COM، لبناء كائن OLE الخاص بنا، فإنّ Qt تتولّى تلقائيًّا كلَّي IDataObject وIPersistStorage. وبذلك لا نحتاج إلّا إلى تنفيذ واجهة IOleObject. وأهمّ استدعاء في هذه الواجهة هو DoVerb. وهو يتيح لـ VisTrails الاستجابة لإجراءات معيّنة من PowerPoint، مثل تنشيط الكائن. وفي تنفيذه، حين يُنشَّط كائن VisTrails، فإنّنا نحمّل تطبيق VisTrails ونتيح للمستخدمين فتح خط أنابيب المعالجة والتفاعل معه واختياره لإدراجه. وبعد أن يغلقوا VisTrails، تظهر نتيجة خط الأنابيب في PowerPoint. كما تُخزَّن معلومات خط الأنابيب مع كائن OLE.

ولتمكين المستخدمين من مشاركة نتائجهم بحرّية إلى جانب المنشأ المرتبط بها، أنشأنا crowdLabs.[7] وcrowdLabs موقع ويب اجتماعي يدمج مجموعة من الأدوات القابلة للاستخدام وبنية تحتية قابلة للتوسّع، لتوفير بيئة للعلماء لتحليل البيانات والتمثيل بها تعاونيًّا. وcrowdLabs مدمج تكامليًّا مع VisTrails. فإذا رغب مستخدم في مشاركة أي نتائج اشتُقّت في VisTrails، فيستطيع الاتصال بخادم crowdLabs مباشرةً من VisTrails لرفع المعلومات. وبعد رفع المعلومات، يستطيع المستخدمون التفاعل مع سِيَر العمل وتنفيذها عبر متصفّح ويب—وتُنفَّذ هذه السِيَر بواسطة خادم VisTrails الذي يشغّل crowdLabs. ولمزيد من التفاصيل عن كيفية استخدام VisTrails لإنشاء منشورات قابلة لإعادة الإنتاج، انظر http://www.vistrails.org.

23.5. الدروس المستفادة

من الحسنّ أنّه في عام 2004، حين بدأنا نفكّر في بناء نظام لاستكشاف البيانات والتمثيل المرئي يدعم المنشأ، لم نتخيّل مدى تحدّي هذه المهمّة، ولا المدّة التي كانت ستستغرقها للوصول إلى النقطة التي نحن عندها الآن. ولو تخيّلنا ذلك، فربّما ما كان الأمر لبدأنا من الأساس.

في البداية، كانت إحدى الاستراتيجيات الناجحة هي بناء نماذج أوّلية سريعة للميزات الجديدة وعرضها على مجموعة مختارة من المستخدمين. وكان الملاحظات الأولية والتشجيع الذي تلقّيناه من هؤلاء المستخدمين أساسيًّا في دفع المشروع إلى الأمام. وربّما كان من المستحيل تصميم VisTrails دون ملاحظات المستخدمين. وإذا كان هناك جانب واحد من المشروع نودّ إبرازه، فهو أنّ معظم الميزات في النظام قد صُمِّمت استجابةً مباشرةً لملاحظات المستخدمين. لكنّ من المهمّ الإشارة إلى أنّ ما يطلبه المستخدم في كثير من الأحيان ليس الحلّ الأمثل لحاجته—والاستجابة للمستخدمين لا تعني بالضرورة تنفيذ ما يطلبونه حرفيًّا. وقد اضطررنا مرارًا وتكرارًا إلى تصميم الميزات وإعادة تصميمها للتأكّد من كونها مفيدة ومدمجة على نحو سليم في النظام.

ونظرًا لمقاربتنا التي تتمركز حول المستخدم، قد يتوقّع المرء أن تُستخدم كل ميزة طوّرناها بكثرة. وللأسف لم يكن الأمر كذلك. وأحيانًا يكون السبب في ذلك أنّ الميزة "غير معتادة" إلى حدٍّ كبير، إذ لا ترد في أدوات أخرى. فمثلًا، التناظرات بل وحتى شجرة الإصدارات ليست مفاهيم مألوفة لدى معظم المستخدمين، وتحتاج بعض الوقت ليألفوها. ومن مسألة مهمّة أخرى هي التوثيق، أو غيابه. فكما في مشاريع المصادر المفتوحة الأخرى كثيرة، كنّا أفضل بكثير في تطوير الميزات الجديدة ممّا كنّا في توثيق الميزات القائمة. وهذا التأخّر في التوثيق يؤدّي ليس إلى قلّة الاستفادة من الميزات المفيدة فحسب، بل أيضًا إلى كثرة الأسئلة على قوائم البريد لدينا.

أحد تحدّيات استخدام نظام مثل VisTrails هو أنّه شديد العمومية. ورغم أفضل جهودنا لتحسين قابلية الاستخدام، فإنّ VisTrails أداة معقّدة وتتطلّب من بعض المستخدمين منحنى تعلّم شديد الانحدار. ونعتقد أنّه مع مرور الوقت، وتحسّن التوثيق، وإجراء تحسينات إضافية على النظام، وتقديم مزيد من الأمثلة الخاصة بالتطبيقات والمجالات، سينخفض حدّ التبنّي في أيّ مجال معيّن. كما أنّه مع انتشار مفهوم المنشأ على نطاق أوسع، سيصبح من الأسهل على المستخدمين فهم الفلسفة التي تبنّيناها في تطوير VisTrails.

23.5.1. شكر وتقدير

نودّ أن نشكر جميع المطوّرين الموهوبين الذين أسهموا في VisTrails: Erik Anderson وLouis Bavoil وClifton Brooks وJason Callahan وSteve Callahan وLorena Carlo وLauro Lins وTommy Ellkvist وPhillip Mates وDaniel Rees وNathan Smith. وشكر خاص لـ Antonio Baptista الذي كان أساسيًّا في مساعدتنا على تطوير رؤية المشروع؛ وMatthias Troyer الذي ساعد تعاونُه في تحسين النظام، ولا سيما في توفير معظم الدافع لتطوير وإطلاق ميزة النشر الغني بالمنشأ. وقد موّل البحث والتطوير في نظام VisTrails، عبر منح IIS 1050422 وIIS-0905385 وIIS 0844572 وATM-0835821 وIIS-0844546 وIIS-0746500 وCNS-0751152 وIIS-0713637 وOCE-0424602 وIIS-0534628 وCNS-0514485 وIIS-0513692 وCNS-0524096 وCCF-0401498 وOISE-0405402 وCCF-0528201 وCNS-0551724، وبإدارة American Department of Energy SciDAC (مركزا VACET وSDM)، وبجائزة IBM Faculty Awards.

الحواشي

  1. http://www.vistrails.org
  2. http://www.hibernate.org
  3. http://www.sqlobject.org
  4. http://www.makotemplates.org
  5. http://www.vtk.org
  6. http://www.vistrails.org/usersguide
  7. http://www.crowdlabs.org

  1. http://www.vistrails.org ↩︎

  2. http://www.hibernate.org ↩︎

  3. http://www.sqlobject.org ↩︎

  4. http://www.makotemplates.org ↩︎

  5. http://www.vtk.org ↩︎

  6. http://www.vistrails.org/usersguide ↩︎

  7. http://www.crowdlabs.org ↩︎