<commit_before># -*- coding: utf-8 -*-
"""Shot related tools
"""
from anima.ui.base import AnimaDialogBase
from anima.ui.lib import QtCore, QtWidgets

class InjectionManager(object):
    """manager for plate injection process

    Contains the general logic
    """

    def __init__(self, project, sequence):
        self.project = project
        self.sequence = sequence
        self.timeline = self.get_current_timeline()

    @classmethod
    def get_current_shot_code(cls):
        """returns the current shot code
        """
        timeline = cls.get_current_timeline()
        clip = cls.get_current_clip()

        plate_injector = PlateInjector()
        plate_injector.timeline = timeline
        plate_injector.clip = clip
        return plate_injector.shot_code

    @classmethod
    def get_current_clip(cls):
        timeline = cls.get_current_timeline()
        clip = timeline.GetCurrentVideoItem()
        return clip

    @classmethod
    def get_current_timeline(cls):
        from anima.env import blackmagic
        resolve = blackmagic.get_resolve()
        pm = resolve.GetProjectManager()
        proj = pm.GetCurrentProject()
        timeline = proj.GetCurrentTimeline()
        return timeline

    @classmethod
    def set_current_shot_code(cls, shot_code):
        """sets the current shot code

        :param str shot_code: The desired shot code
        """
        timeline = cls.get_current_timeline()

        plate_injector = PlateInjector()
        plate_injector.clip = timeline.GetCurrentVideoItem()
        plate_injector.set_shot_code(shot_code)

    def get_clip_list(self):
        """returns the clips
        """
        timeline = self.get_current_timeline()
        clips = timeline.GetItemListInTrack('video', 1)
        return clips

    def get_shot_list(self):
        """returns the shots in the current video track
        """
        shot_list = []
        clips = self.get_clip_list()
        for clip in clips:
            pi = PlateInjector(project=self.project, sequence=self.sequence, clip=clip, timeline=self.timeline)
            if pi.is_shot():
                shot_list.append(pi)
        return shot_list

    def get_thumbnail(cls):
        """returns the current media thumbnail
        """
        timeline = cls.get_current_timeline()

        plate_injector = PlateInjector()
        plate_injector.timeline = timeline
        plate_injector.clip = timeline.GetCurrentVideoItem()
        thumbnail = plate_injector.update_shot_thumbnail()
        return thumbnail

class PlateInjector(object):
    """Renders plates for the given clip

    Generates render jobs that renders the VFX related clips in the current
    timeline to their respective shot folder.
    """

    def __init__(self, project=None, sequence=None, clip=None, timeline=None):
        self.project = project
        self.sequence = sequence
        self.timeline = timeline
        self.clip = clip
        self._shot_code = None

    def create_shot(self):
        """creates the related shot
        """
        from stalker import Shot, Task
        from stalker.db.session import DBSession
        shot = Shot.query.filter(Shot.project==self.project).filter(Shot.code==self.shot_code).first()
        if not shot:
            # create the shot

            logged_in_user = self.get_logged_in_user()

            # FP001_001_0010
            scene_code = self.shot_code.split("_")[1]
            scene_task = Task.query.filter(Task.parent==self.sequence).filter(Task.name.contains(scene_code)).first()

            if not scene_task:
                # create the scene task
                scene_task = Task(
                    project=self.project,
                    name='SCN%s' % scene_code,
                    parent=self.sequence,
                    description='Autocreated by PlateInjector',
                    created_by=logged_in_user,
                    updated_by=logged_in_user,
                )
                DBSession.add(scene_task)
                DBSession.commit()

            shots_task = Task.query.filter(Task.parent==scene_task).filter(Task.name=='Shots').first()
            if not shots_task:
                shots_task = Task(
                    project=self.project,
                    name='Shots',
                    parent=scene_task,
                    description='Autocreated by PlateInjector',
                    created_by=logged_in_user,
                    updated_by=logged_in_user,
                )
                DBSession.add(shots_task)
                DBSession.commit()

            shot = Shot(
                name=self.shot_code,
                code=self.shot_code,
                project=self.project,
                parent=shots_task,
                sequences=[self.sequence],
                cut_in=1001,
                cut_out=self.clip.GetEnd() - self.clip.GetStart() + 1000,
                description='Autocreated by PlateInjector',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(shot)

            # creat shot tasks
            # Anim
            anim_task = Task(
                name='Anim',
                parent=shot,
                type=self.get_type('Animation'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(anim_task)

            # Camera
            camera_task = Task(
                name='Camera',
                parent=shot,
                type=self.get_type('Camera'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(camera_task)

            # Cleanup
            cleanup_task = Task(
                name='Cleanup',
                parent=shot,
                type=self.get_type('Comp'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(cleanup_task)

            # Comp
            comp_task = Task(
                name='Comp',
                parent=shot,
                type=self.get_type('Comp'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(comp_task)

            # Lighting
            lighting_task = Task(
                name='Lighting',
                parent=shot,
                type=self.get_type('Lighting'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(lighting_task)

            # Plate
            plate_task = Task(
                name='Plate',
                parent=shot,
                type=self.get_type('Plate'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(plate_task)

            # add dependency relation
            camera_task.depends = [plate_task]
            anim_task.depends = [camera_task]
            lighting_task.depends = [anim_task]
            cleanup_task.depends = [plate_task]
            comp_task.depends = [lighting_task, cleanup_task]

            DBSession.commit()

        return shot

    def update_shot_thumbnail(self):
        """updates the shot thumbnail from resolve
        """
        # go to the color page to retrieve the thumbnail
        from anima.env import blackmagic
        resolve = blackmagic.get_resolve()
        resolve.OpenPage('color')
        current_media_thumbnail = self.timeline.GetCurrentClipThumbnailImage()
        resolve.OpenPage('edit')

        from PIL import Image
        from io import BytesIO
        import base64
        im = Image.open(BytesIO(base64.b64decode(current_media_thumbnail['data'])))

        with open('/home/eoyilmaz/resolve_raw_thumbnail_data', 'w+') as f:
            f.write(current_media_thumbnail['data'])

        import tempfile
        thumbnail_path = tempfile.mktemp(suffix='.jpg')
        print('thumbnail_path: %s' % thumbnail_path)
        im.save(thumbnail_path, quality=85)

        return current_media_thumbnail

    @classmethod
    def get_logged_in_user(cls):
        """returns the logged in user
        """
        # get logged in user
        from stalker import LocalSession
        from stalker.db.session import DBSession

        local_session = LocalSession()
        with DBSession.no_autoflush:
            logged_in_user = local_session.logged_in_user

        if not logged_in_user:
            raise RuntimeError("Please login first!")

        return logged_in_user

    def get_type(self, type_name):
        """returns the Stalker Type instance with the given name, if the type doesn't exist it will create it

        :param str type_name: Type queried type name

        :return:
        """
        from stalker import Type
        type_instance = Type.query.filter(Type.name==type_name).first()
        if not type_instance:
            logged_in_user = self.get_logged_in_user()
            type_instance = Type(
                entity_type='Task',
                name=type_name,
                created_by=logged_in_user,
                updated_by=logged_in_user
            )
            from stalker.db.session import DBSession
            DBSession.add(type_instance)
            DBSession.commit()
        return type_instance

    def create_render_job(self):
        """creates render job for the clip
        """
        # create a new render output for each clip
        from anima.env import blackmagic
        resolve = blackmagic.get_resolve()

        pm = resolve.GetProjectManager()
        proj = pm.GetCurrentProject()

        # get the shot
        from stalker import Task, Shot, Type
        shot = Shot.query.filter(Shot.project==self.project).filter(Shot.code==self.shot_code).first()
        if not shot:
            # raise RuntimeError("No shot with code: %s" % self.shot_code)
            shot = self.create_shot()

        # get plate task
        plate_type = Type.query.filter(Type.name=='Plate').first()
        if not plate_type:
            raise RuntimeError("No plate type!!!")

        plate_task = Task.query.filter(Task.parent==shot).filter(Task.type==plate_type).first()
        if not plate_task:
            raise RuntimeError("No plate task in shot: %s" % self.shot_code)

        proj.SetCurrentRenderFormatAndCodec('exr', 'RGBHalfZIP')

        proj.SetRenderSettings({
            'MarkIn': self.clip.GetStart(),
            'MarkOut': self.clip.GetEnd() - 1,
            'CustomName': '%s_Main_v001' % self.shot_code,
            'TargetDir': '%s/Outputs/Main/v001/exr' % plate_task.absolute_path
        })
        proj.AddRenderJob()

    def get_shot_related_marker(self):
        """returns the shot related marker data
        """
        clip_start_frame = self.clip.GetStart()
        timeline_start_frame = self.timeline.GetStartFrame()
        markers = self.timeline.GetMarkers()
        if markers:
            keys = markers.keys()
            frame_id = clip_start_frame - timeline_start_frame
            try:
                marker = markers[frame_id]
            except KeyError:
                return None

            marker['frameId'] = frame_id
            return marker

    def is_shot(self):
        """returns True if this is a shot clip
        """
        if self.shot_code:
            return True
        else:
            return False

    @property
    def shot_code(self):
        """Returns the shot code of the given clip

        :return:
        """
        if not self._shot_code:
            marker = self.get_shot_related_marker()
            if marker:
                self._shot_code = marker['note']

        return self._shot_code

    @shot_code.setter
    def shot_code(self, shot_code):
        """Sets the shot code of the given clip

        :return:
        """
        self._shot_code = None
        marker = self.get_shot_related_marker()

        if marker:
            self.timeline.DeleteMarkerAtFrame(marker['frameId'])

        # create a new marker
        result = self.timeline.AddMarker(
            frameId=self.clip.GetStart() - self.timeline.GetStartFrame(),
            color='Blue',
            name='Marker 1',
            note=shot_code,
            duration=1,
        )

        print("result: %s" % result)

class PlateInjectorUI(QtWidgets.QDialog, AnimaDialogBase):
    """The UI for the PlateInjector
    """

    def __init__(self, *args, **kwargs):
        super(PlateInjectorUI, self).__init__(*args, **kwargs)
        self.main_layout = None
        self.form_layout = None
        self.project_combo_box = None
        self.sequence_combo_box = None
        self.setup_ui()

    def setup_ui(self):
        """sets the ui up
        """
        from anima.utils import do_db_setup
        do_db_setup()

        # get logged in user
        self.get_logged_in_user()

        self.setWindowTitle("Plate Injector")

        self.main_layout = QtWidgets.QVBoxLayout(self)
        self.form_layout = QtWidgets.QFormLayout(self)
        self.main_layout.addLayout(self.form_layout)

        i = 0
        # Project
        label = QtWidgets.QLabel(self)
        label.setText("Project")
        self.form_layout.setWidget(
            i,
            QtWidgets.QFormLayout.LabelRole,
            label
        )

        from anima.ui.widgets.project import ProjectComboBox
        self.project_combo_box = ProjectComboBox(self)
        self.form_layout.setWidget(
            i,
            QtWidgets.QFormLayout.FieldRole,
            self.project_combo_box
        )

        # Sequence
        i += 1
        label = QtWidgets.QLabel(self)
        label.setText("Sequence")
        self.form_layout.setWidget(
            i,
            QtWidgets.QFormLayout.LabelRole,
            label
        )

        from anima.ui.widgets.sequence import SequenceComboBox
        self.sequence_combo_box = SequenceComboBox(self)
        self.form_layout.setWidget(
            i,
            QtWidgets.QFormLayout.FieldRole,
            self.sequence_combo_box
        )

        # Get Shot List button
        get_shot_list_push_button = QtWidgets.QPushButton(self)
        get_shot_list_push_button.setText("Get Shot List")
        self.main_layout.addWidget(get_shot_list_push_button)

        # Create Render Jobs button
        create_render_jobs_button = QtWidgets.QPushButton(self)
        create_render_jobs_button.setText("Create Render Jobs")
        self.main_layout.addWidget(create_render_jobs_button)

        # Ok button
        ok_button = QtWidgets.QPushButton(self)
        ok_button.setText("OK")
        self.main_layout.addWidget(ok_button)

        # Signals
        self.project_changed(None)

        QtCore.QObject.connect(
            self.project_combo_box,
            QtCore.SIGNAL("currentIndexChanged(QString)"),
            self.project_changed
        )

        QtCore.QObject.connect(
            ok_button,
            QtCore.SIGNAL("clicked()"),
            self.do_something
        )

        QtCore.QObject.connect(
            create_render_jobs_button,
            QtCore.SIGNAL("clicked()"),
            self.create_render_jobs
        )

        QtCore.QObject.connect(
            get_shot_list_push_button,
            QtCore.SIGNAL("clicked()"),
            self.get_shot_list
        )

    def project_changed(self, index):
        """runs when the current selected project has been changed
        """
        self.sequence_combo_box.project = self.project_combo_box.get_current_project()

    def do_something(self):
        """
        """
        project = self.project_combo_box.get_current_project()
        print(project.name)

    def get_shot_list(self):
        """just prints the shot names
        """
        project = self.project_combo_box.get_current_project()
        sequence = self.sequence_combo_box.get_current_sequence()
        im = InjectionManager(project, sequence)
        for shot in im.get_shot_list():
            isinstance(shot, PlateInjector)
            print(shot.shot_code)

    def create_render_jobs(self):
        """creates render jobs
        """
        project = self.project_combo_box.get_current_project()
        sequence = self.sequence_combo_box.get_current_sequence()
        im = InjectionManager(project, sequence)

        try:
            for shot in im.get_shot_list():
                isinstance(shot, PlateInjector)
                shot.create_render_job()
        except BaseException as e:
            QtWidgets.QMessageBox.critical(
                self,
                "Error",
                str(e)
            )
        finally:
            QtWidgets.QMessageBox.information(
                self,
                "Created Shots and Render Jobs!!!",
                "Created Shots and Render Jobs!!!"
            )<commit_msg>* [Resolve] ``PlateInjector`` now loads a render template with the name ``PlateInjector``. * [Resolve] ``PlateInjector`` now can render with "." signs between the filename and frame number.<commit_after># -*- coding: utf-8 -*-
"""Shot related tools
"""
from anima.ui.base import AnimaDialogBase
from anima.ui.lib import QtCore, QtWidgets

class InjectionManager(object):
    """manager for plate injection process

    Contains the general logic
    """

    def __init__(self, project, sequence):
        self.project = project
        self.sequence = sequence
        self.timeline = self.get_current_timeline()

    @classmethod
    def get_current_shot_code(cls):
        """returns the current shot code
        """
        timeline = cls.get_current_timeline()
        clip = cls.get_current_clip()

        plate_injector = PlateInjector()
        plate_injector.timeline = timeline
        plate_injector.clip = clip
        return plate_injector.shot_code

    @classmethod
    def get_current_clip(cls):
        timeline = cls.get_current_timeline()
        clip = timeline.GetCurrentVideoItem()
        return clip

    @classmethod
    def get_current_timeline(cls):
        from anima.env import blackmagic
        resolve = blackmagic.get_resolve()
        pm = resolve.GetProjectManager()
        proj = pm.GetCurrentProject()
        timeline = proj.GetCurrentTimeline()
        return timeline

    @classmethod
    def set_current_shot_code(cls, shot_code):
        """sets the current shot code

        :param str shot_code: The desired shot code
        """
        timeline = cls.get_current_timeline()

        plate_injector = PlateInjector()
        plate_injector.clip = timeline.GetCurrentVideoItem()
        plate_injector.set_shot_code(shot_code)

    def get_clip_list(self):
        """returns the clips
        """
        timeline = self.get_current_timeline()
        clips = timeline.GetItemListInTrack('video', 1)
        return clips

    def get_shot_list(self):
        """returns the shots in the current video track
        """
        shot_list = []
        clips = self.get_clip_list()
        for clip in clips:
            pi = PlateInjector(project=self.project, sequence=self.sequence, clip=clip, timeline=self.timeline)
            if pi.is_shot():
                shot_list.append(pi)
        return shot_list

    def get_thumbnail(cls):
        """returns the current media thumbnail
        """
        timeline = cls.get_current_timeline()

        plate_injector = PlateInjector()
        plate_injector.timeline = timeline
        plate_injector.clip = timeline.GetCurrentVideoItem()
        thumbnail = plate_injector.update_shot_thumbnail()
        return thumbnail

class PlateInjector(object):
    """Renders plates for the given clip

    Generates render jobs that renders the VFX related clips in the current
    timeline to their respective shot folder.
    """

    def __init__(self, project=None, sequence=None, clip=None, timeline=None):
        self.project = project
        self.sequence = sequence
        self.timeline = timeline
        self.clip = clip
        self._shot_code = None

    def create_shot(self):
        """creates the related shot
        """
        from stalker import Shot, Task
        from stalker.db.session import DBSession
        shot = Shot.query.filter(Shot.project==self.project).filter(Shot.code==self.shot_code).first()
        if not shot:
            # create the shot

            logged_in_user = self.get_logged_in_user()

            # FP001_001_0010
            scene_code = self.shot_code.split("_")[1]
            scene_task = Task.query.filter(Task.parent==self.sequence).filter(Task.name.contains(scene_code)).first()

            if not scene_task:
                # create the scene task
                scene_task = Task(
                    project=self.project,
                    name='SCN%s' % scene_code,
                    parent=self.sequence,
                    description='Autocreated by PlateInjector',
                    created_by=logged_in_user,
                    updated_by=logged_in_user,
                )
                DBSession.add(scene_task)
                DBSession.commit()

            shots_task = Task.query.filter(Task.parent==scene_task).filter(Task.name=='Shots').first()
            if not shots_task:
                shots_task = Task(
                    project=self.project,
                    name='Shots',
                    parent=scene_task,
                    description='Autocreated by PlateInjector',
                    created_by=logged_in_user,
                    updated_by=logged_in_user,
                )
                DBSession.add(shots_task)
                DBSession.commit()

            shot = Shot(
                name=self.shot_code,
                code=self.shot_code,
                project=self.project,
                parent=shots_task,
                sequences=[self.sequence],
                cut_in=1001,
                cut_out=self.clip.GetEnd() - self.clip.GetStart() + 1000,
                description='Autocreated by PlateInjector',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(shot)

            # creat shot tasks
            # Anim
            anim_task = Task(
                name='Anim',
                parent=shot,
                type=self.get_type('Animation'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(anim_task)

            # Camera
            camera_task = Task(
                name='Camera',
                parent=shot,
                type=self.get_type('Camera'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(camera_task)

            # Cleanup
            cleanup_task = Task(
                name='Cleanup',
                parent=shot,
                type=self.get_type('Comp'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(cleanup_task)

            # Comp
            comp_task = Task(
                name='Comp',
                parent=shot,
                type=self.get_type('Comp'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(comp_task)

            # Lighting
            lighting_task = Task(
                name='Lighting',
                parent=shot,
                type=self.get_type('Lighting'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(lighting_task)

            # Plate
            plate_task = Task(
                name='Plate',
                parent=shot,
                type=self.get_type('Plate'),
                bid_timing=10,
                bid_unit='min',
                created_by=logged_in_user,
                updated_by=logged_in_user,
            )
            DBSession.add(plate_task)

            # add dependency relation
            camera_task.depends = [plate_task]
            anim_task.depends = [camera_task]
            lighting_task.depends = [anim_task]
            cleanup_task.depends = [plate_task]
            comp_task.depends = [lighting_task, cleanup_task]

            DBSession.commit()

        return shot

    def update_shot_thumbnail(self):
        """updates the shot thumbnail from resolve
        """
        # go to the color page to retrieve the thumbnail
        from anima.env import blackmagic
        resolve = blackmagic.get_resolve()
        resolve.OpenPage('color')
        current_media_thumbnail = self.timeline.GetCurrentClipThumbnailImage()
        resolve.OpenPage('edit')

        from PIL import Image
        from io import BytesIO
        import base64
        im = Image.open(BytesIO(base64.b64decode(current_media_thumbnail['data'])))

        with open('/home/eoyilmaz/resolve_raw_thumbnail_data', 'w+') as f:
            f.write(current_media_thumbnail['data'])

        import tempfile
        thumbnail_path = tempfile.mktemp(suffix='.jpg')
        print('thumbnail_path: %s' % thumbnail_path)
        im.save(thumbnail_path, quality=85)

        return current_media_thumbnail

    @classmethod
    def get_logged_in_user(cls):
        """returns the logged in user
        """
        # get logged in user
        from stalker import LocalSession
        from stalker.db.session import DBSession

        local_session = LocalSession()
        with DBSession.no_autoflush:
            logged_in_user = local_session.logged_in_user

        if not logged_in_user:
            raise RuntimeError("Please login first!")

        return logged_in_user

    def get_type(self, type_name):
        """returns the Stalker Type instance with the given name, if the type doesn't exist it will create it

        :param str type_name: Type queried type name

        :return:
        """
        from stalker import Type
        type_instance = Type.query.filter(Type.name==type_name).first()
        if not type_instance:
            logged_in_user = self.get_logged_in_user()
            type_instance = Type(
                entity_type='Task',
                name=type_name,
                created_by=logged_in_user,
                updated_by=logged_in_user
            )
            from stalker.db.session import DBSession
            DBSession.add(type_instance)
            DBSession.commit()
        return type_instance

    def create_render_job(self):
        """creates render job for the clip
        """
        # create a new render output for each clip
        from anima.env import blackmagic
        resolve = blackmagic.get_resolve()

        pm = resolve.GetProjectManager()
        proj = pm.GetCurrentProject()

        template_name = "PlateInjector"
        result = proj.LoadRenderPreset(template_name)
        if not result:
            print("No template named: %s" % template_name)
        else:
            print("Template loaded successfully: %s" % template_name)

        # get the shot
        from stalker import Task, Shot, Type
        shot = Shot.query.filter(Shot.project==self.project).filter(Shot.code==self.shot_code).first()
        if not shot:
            # raise RuntimeError("No shot with code: %s" % self.shot_code)
            shot = self.create_shot()

        # get plate task
        plate_type = Type.query.filter(Type.name=='Plate').first()
        if not plate_type:
            raise RuntimeError("No plate type!!!")

        plate_task = Task.query.filter(Task.parent==shot).filter(Task.type==plate_type).first()
        if not plate_task:
            raise RuntimeError("No plate task in shot: %s" % self.shot_code)

        proj.SetCurrentRenderFormatAndCodec('exr', 'RGBHalfZIP')

        proj.SetRenderSettings({
            'MarkIn': self.clip.GetStart(),
            'MarkOut': self.clip.GetEnd() - 1,
            'CustomName': '%s_Main_v001.' % self.shot_code,
            'TargetDir': '%s/Outputs/Main/v001/exr' % plate_task.absolute_path
        })
        proj.SetCurrentRenderMode(1)
        proj.AddRenderJob()

    def get_shot_related_marker(self):
        """returns the shot related marker data
        """
        clip_start_frame = self.clip.GetStart()
        timeline_start_frame = self.timeline.GetStartFrame()
        markers = self.timeline.GetMarkers()
        if markers:
            keys = markers.keys()
            frame_id = clip_start_frame - timeline_start_frame
            try:
                marker = markers[frame_id]
            except KeyError:
                return None

            marker['frameId'] = frame_id
            return marker

    def is_shot(self):
        """returns True if this is a shot clip
        """
        if self.shot_code:
            return True
        else:
            return False

    @property
    def shot_code(self):
        """Returns the shot code of the given clip

        :return:
        """
        if not self._shot_code:
            marker = self.get_shot_related_marker()
            if marker:
                self._shot_code = marker['note']

        return self._shot_code

    @shot_code.setter
    def shot_code(self, shot_code):
        """Sets the shot code of the given clip

        :return:
        """
        self._shot_code = None
        marker = self.get_shot_related_marker()

        if marker:
            self.timeline.DeleteMarkerAtFrame(marker['frameId'])

        # create a new marker
        result = self.timeline.AddMarker(
            frameId=self.clip.GetStart() - self.timeline.GetStartFrame(),
            color='Blue',
            name='Marker 1',
            note=shot_code,
            duration=1,
        )

        print("result: %s" % result)

class PlateInjectorUI(QtWidgets.QDialog, AnimaDialogBase):
    """The UI for the PlateInjector
    """

    def __init__(self, *args, **kwargs):
        super(PlateInjectorUI, self).__init__(*args, **kwargs)
        self.main_layout = None
        self.form_layout = None
        self.project_combo_box = None
        self.sequence_combo_box = None
        self.setup_ui()

    def setup_ui(self):
        """sets the ui up
        """
        from anima.utils import do_db_setup
        do_db_setup()

        # get logged in user
        self.get_logged_in_user()

        self.setWindowTitle("Plate Injector")

        self.main_layout = QtWidgets.QVBoxLayout(self)
        self.form_layout = QtWidgets.QFormLayout(self)
        self.main_layout.addLayout(self.form_layout)

        i = 0
        # Project
        label = QtWidgets.QLabel(self)
        label.setText("Project")
        self.form_layout.setWidget(
            i,
            QtWidgets.QFormLayout.LabelRole,
            label
        )

        from anima.ui.widgets.project import ProjectComboBox
        self.project_combo_box = ProjectComboBox(self)
        self.form_layout.setWidget(
            i,
            QtWidgets.QFormLayout.FieldRole,
            self.project_combo_box
        )

        # Sequence
        i += 1
        label = QtWidgets.QLabel(self)
        label.setText("Sequence")
        self.form_layout.setWidget(
            i,
            QtWidgets.QFormLayout.LabelRole,
            label
        )

        from anima.ui.widgets.sequence import SequenceComboBox
        self.sequence_combo_box = SequenceComboBox(self)
        self.form_layout.setWidget(
            i,
            QtWidgets.QFormLayout.FieldRole,
            self.sequence_combo_box
        )

        # Get Shot List button
        get_shot_list_push_button = QtWidgets.QPushButton(self)
        get_shot_list_push_button.setText("Get Shot List")
        self.main_layout.addWidget(get_shot_list_push_button)

        # Create Render Jobs button
        create_render_jobs_button = QtWidgets.QPushButton(self)
        create_render_jobs_button.setText("Create Render Jobs")
        self.main_layout.addWidget(create_render_jobs_button)

        # Ok button
        ok_button = QtWidgets.QPushButton(self)
        ok_button.setText("OK")
        self.main_layout.addWidget(ok_button)

        # Signals
        self.project_changed(None)

        QtCore.QObject.connect(
            self.project_combo_box,
            QtCore.SIGNAL("currentIndexChanged(QString)"),
            self.project_changed
        )

        QtCore.QObject.connect(
            ok_button,
            QtCore.SIGNAL("clicked()"),
            self.do_something
        )

        QtCore.QObject.connect(
            create_render_jobs_button,
            QtCore.SIGNAL("clicked()"),
            self.create_render_jobs
        )

        QtCore.QObject.connect(
            get_shot_list_push_button,
            QtCore.SIGNAL("clicked()"),
            self.get_shot_list
        )

    def project_changed(self, index):
        """runs when the current selected project has been changed
        """
        self.sequence_combo_box.project = self.project_combo_box.get_current_project()

    def do_something(self):
        """
        """
        project = self.project_combo_box.get_current_project()
        print(project.name)

    def get_shot_list(self):
        """just prints the shot names
        """
        project = self.project_combo_box.get_current_project()
        sequence = self.sequence_combo_box.get_current_sequence()
        im = InjectionManager(project, sequence)
        for shot in im.get_shot_list():
            isinstance(shot, PlateInjector)
            print(shot.shot_code)

    def create_render_jobs(self):
        """creates render jobs
        """
        project = self.project_combo_box.get_current_project()
        sequence = self.sequence_combo_box.get_current_sequence()
        im = InjectionManager(project, sequence)

        try:
            for shot in im.get_shot_list():
                isinstance(shot, PlateInjector)
                shot.create_render_job()
        except BaseException as e:
            QtWidgets.QMessageBox.critical(
                self,
                "Error",
                str(e)
            )
            raise e
        finally:
            QtWidgets.QMessageBox.information(
                self,
                "Created Shots and Render Jobs!!!",
                "Created Shots and Render Jobs!!!"
            )<|endoftext|>


<commit_before>import logging
from inspect import getmembers
from os.path import join, exists, dirname
from os import makedirs

from django.core.management.base import BaseCommand
from django.utils.importlib import import_module
from devilry.apps import extjshelpers

from devilry.restful import RestfulManager
from devilry.utils.command import setup_logging, get_verbosity
from devilry.utils.importutils import get_installed_apps
from devilry.apps.extjshelpers.modelintegration import (restfulcls_to_extjsmodel,
                                                        get_extjs_modelname)

def get_restful_apps():
    apps = []
    for moddir, mod, appname in get_installed_apps():
        try:
            restfulmodule = import_module('{0}.{1}'.format(mod.__name__, 'restful'))
        except ImportError, e:
            pass
        else:
            apps.append((moddir, restfulmodule, appname))
    return apps

class Command(BaseCommand):
    help = 'Autogenerate ExtJS models from restful interfaces.'

    fileheader = '// Autogenerated by the dev_coreextjsmodels script. DO NOT CHANGE MANUALLY'

    def handle(self, *args, **options):
        setup_logging(get_verbosity(options))
        all_modelnames = self._create_files_for_all_modules(get_restful_apps())
        self._create_requireall_file(all_modelnames)

    def _create_files_for_all_modules(self, restful_apps):
        all_modelnames = []
        for moddir, restfulmodule, appname in restful_apps:
            modelnames = self._create_files_for_module(moddir, restfulmodule, appname)
            all_modelnames += modelnames
        return all_modelnames

    def _create_files_for_module(self, moddir, restfulmodule, appname):
        modelnames = []
        logging.info('Parsing app: %s', appname)
        self._get_restfulmanagers(restfulmodule)
        for restfulmanager in self._get_restfulmanagers(restfulmodule):
            for restfulcls in restfulmanager.iter_restfulclasses():
                logging.debug('Generating JS code for: %s', restfulcls.__name__)
                js = self._get_js_for_model(restfulcls)
                modelname = get_extjs_modelname(restfulcls)
                self._create_extjsclassfile(moddir, modelname, js)
                modelnames.append(modelname)
        return modelnames

    def _get_restfulmanagers(self, restfulmodule):
        def is_restfulmananager_obj(obj):
            return isinstance(obj, RestfulManager)
        return [manager for name, manager in getmembers(restfulmodule, is_restfulmananager_obj)]

    def _create_requireall_file(self, modelnames):
        extjshelpersdir = dirname(extjshelpers.__file__)
        requires = ',\n'.join(["    '{0}'".format(modelname) for modelname in modelnames])
        content = ('{{% comment %}}\n'
                   '{0}\n'
                   '// This is a Django template because we want to make it easy to dump it into the page template.\n'
                   '{{% endcomment %}}'
                   '\nExt.require([\n{1}\n]);').format(self.fileheader, requires)
        dirpath = join(extjshelpersdir, 'templates', 'extjshelpers')
        path = join(dirpath, 'restful-generated-models.django.js')
        logging.info('Creating: %s', path)
        logging.debug('%s: %s', path, content)
        makedirs(dirpath)
        open(path, 'w').write(content)

    def _get_js_for_model(self, restfulcls):
        result_fieldgroups =  restfulcls._meta.simplified._meta.resultfields.additional_aslist()
        js = restfulcls_to_extjsmodel(restfulcls, result_fieldgroups, pretty=True)
        return js + ';'

    def _create_extjsclass_dir(self, moddir, modelname):
        path = modelname.split('.')[1:-1]
        directory = join(moddir, 'static', 'extjs_classes', *path)
        if not exists(directory):
            logging.info('Creating directory: %s', directory)
            makedirs(directory)
        return directory

    def _create_extjsclassfile(self, moddir, modelname, js):
        directory = self._create_extjsclass_dir(moddir, modelname)
        clsname = modelname.split('.')[-1]
        data = '{0}\n{1}'.format(self.fileheader, js)
        path = join(directory, clsname + '.js')
        logging.info('Creating: %s', path)
        logging.debug('%s: %s', path, data)
        open(path, 'w').write(data)
<commit_msg>developertools...dev_autogen_extjsmodels: Check if target dir exists.<commit_after>import logging
from inspect import getmembers
from os.path import join, exists, dirname
from os import makedirs

from django.core.management.base import BaseCommand
from django.utils.importlib import import_module
from devilry.apps import extjshelpers

from devilry.restful import RestfulManager
from devilry.utils.command import setup_logging, get_verbosity
from devilry.utils.importutils import get_installed_apps
from devilry.apps.extjshelpers.modelintegration import (restfulcls_to_extjsmodel,
                                                        get_extjs_modelname)

def get_restful_apps():
    apps = []
    for moddir, mod, appname in get_installed_apps():
        try:
            restfulmodule = import_module('{0}.{1}'.format(mod.__name__, 'restful'))
        except ImportError, e:
            pass
        else:
            apps.append((moddir, restfulmodule, appname))
    return apps

class Command(BaseCommand):
    help = 'Autogenerate ExtJS models from restful interfaces.'

    fileheader = '// Autogenerated by the dev_coreextjsmodels script. DO NOT CHANGE MANUALLY'

    def handle(self, *args, **options):
        setup_logging(get_verbosity(options))
        all_modelnames = self._create_files_for_all_modules(get_restful_apps())
        self._create_requireall_file(all_modelnames)

    def _create_files_for_all_modules(self, restful_apps):
        all_modelnames = []
        for moddir, restfulmodule, appname in restful_apps:
            modelnames = self._create_files_for_module(moddir, restfulmodule, appname)
            all_modelnames += modelnames
        return all_modelnames

    def _create_files_for_module(self, moddir, restfulmodule, appname):
        modelnames = []
        logging.info('Parsing app: %s', appname)
        self._get_restfulmanagers(restfulmodule)
        for restfulmanager in self._get_restfulmanagers(restfulmodule):
            for restfulcls in restfulmanager.iter_restfulclasses():
                logging.debug('Generating JS code for: %s', restfulcls.__name__)
                js = self._get_js_for_model(restfulcls)
                modelname = get_extjs_modelname(restfulcls)
                self._create_extjsclassfile(moddir, modelname, js)
                modelnames.append(modelname)
        return modelnames

    def _get_restfulmanagers(self, restfulmodule):
        def is_restfulmananager_obj(obj):
            return isinstance(obj, RestfulManager)
        return [manager for name, manager in getmembers(restfulmodule, is_restfulmananager_obj)]

    def _create_requireall_file(self, modelnames):
        extjshelpersdir = dirname(extjshelpers.__file__)
        requires = ',\n'.join(["    '{0}'".format(modelname) for modelname in modelnames])
        content = ('{{% comment %}}\n'
                   '{0}\n'
                   '// This is a Django template because we want to make it easy to dump it into the page template.\n'
                   '{{% endcomment %}}'
                   '\nExt.require([\n{1}\n]);').format(self.fileheader, requires)
        dirpath = join(extjshelpersdir, 'templates', 'extjshelpers')
        path = join(dirpath, 'restful-generated-models.django.js')
        logging.info('Creating: %s', path)
        logging.debug('%s: %s', path, content)
        if not exists(dirpath):
            makedirs(dirpath)
        open(path, 'w').write(content)

    def _get_js_for_model(self, restfulcls):
        result_fieldgroups =  restfulcls._meta.simplified._meta.resultfields.additional_aslist()
        js = restfulcls_to_extjsmodel(restfulcls, result_fieldgroups, pretty=True)
        return js + ';'

    def _create_extjsclass_dir(self, moddir, modelname):
        path = modelname.split('.')[1:-1]
        directory = join(moddir, 'static', 'extjs_classes', *path)
        if not exists(directory):
            logging.info('Creating directory: %s', directory)
            makedirs(directory)
        return directory

    def _create_extjsclassfile(self, moddir, modelname, js):
        directory = self._create_extjsclass_dir(moddir, modelname)
        clsname = modelname.split('.')[-1]
        data = '{0}\n{1}'.format(self.fileheader, js)
        path = join(directory, clsname + '.js')
        logging.info('Creating: %s', path)
        logging.debug('%s: %s', path, data)
        open(path, 'w').write(data)
<|endoftext|>


<commit_before>dev_requires = [
    "pydmt",
]
make_requires = [
    "pymakehelper",
]
<commit_msg>deps change<commit_after>make_requires = [
    "pymakehelper",
    "pydmt",
    "pyclassifiers",
]
<|endoftext|>


<commit_before>from __future__ import division

import os
import libtbx.load_env
from cctbx import crystal, miller, sgtbx
from scitbx import matrix
from dxtbx.serialize import load
from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList
from dxtbx.model.crystal import crystal_model
from dials.array_family import flex

# set random seeds so tests more reliable

seed = 54321

import random
random.seed(seed)
import scitbx.random
scitbx.random.set_random_seed(seed)

have_dials_regression = libtbx.env.has_module("dials_regression")
if have_dials_regression:
  dials_regression = libtbx.env.find_in_repositories(
    relative_path="dials_regression",
    test=os.path.isdir)

def random_rotation(angle_min=0, angle_max=360):
  import random
  from scitbx.math import euler_angles_as_matrix
  return euler_angles_as_matrix(
    [random.uniform(angle_min,angle_max) for i in xrange(3)])

def run(space_group_info):
  datablock_json = os.path.join(
    dials_regression, "indexing_test_data",
    "i04_weak_data", "datablock_orig.json")

  datablock = load.datablock(datablock_json, check_format=False)[0]
  sweep = datablock.extract_imagesets()[0]

  sweep._indices = sweep._indices[:20]
  sweep.set_scan(sweep.get_scan()[:20])

  import random
  space_group = space_group_info.group()
  unit_cell = space_group_info.any_compatible_unit_cell(volume=random.uniform(1e4,1e6))

  crystal_symmetry = crystal.symmetry(unit_cell=unit_cell,
                                      space_group=space_group)
  crystal_symmetry.show_summary()

  # the reciprocal matrix
  B = matrix.sqr(unit_cell.fractionalization_matrix()).transpose()
  U = random_rotation()
  A = U * B

  direct_matrix = A.inverse()
  cryst_model = crystal_model(direct_matrix[0:3],
                              direct_matrix[3:6],
                              direct_matrix[6:9],
                              space_group=space_group)
  experiment = Experiment(imageset=sweep,
                          beam=sweep.get_beam(),
                          detector=sweep.get_detector(),
                          goniometer=sweep.get_goniometer(),
                          scan=sweep.get_scan(),
                          crystal=cryst_model)
  predicted_reflections = flex.reflection_table.from_predictions(
    experiment)
  use_fraction = 0.3
  use_sel = flex.random_selection(
    len(predicted_reflections), int(use_fraction*len(predicted_reflections)))
  predicted_reflections = predicted_reflections.select(use_sel)
  miller_indices = predicted_reflections['miller_index']
  miller_set = miller.set(
    crystal_symmetry, miller_indices, anomalous_flag=True)
  predicted_reflections['xyzobs.mm.value'] = predicted_reflections['xyzcal.mm']
  predicted_reflections['id'] = flex.size_t(len(predicted_reflections), 0)
  from dials.algorithms.indexing.indexer import indexer_base
  indexer_base.map_centroids_to_reciprocal_space(
    predicted_reflections, sweep.get_detector(), sweep.get_beam(),
    sweep.get_goniometer())

  # check that local and global indexing worked equally well in absence of errors
  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)
  assert result.misindexed_local == 0
  assert result.misindexed_global == 0

  a, b, c = cryst_model.get_real_space_vectors()
  relative_error = 0.02
  a *= (1+relative_error)
  b *= (1+relative_error)
  c *= (1+relative_error)

  cryst_model2 = crystal_model(a, b, c, space_group=space_group)
  experiment.crystal = cryst_model2

  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)

  # check that the local indexing did a better job given the errors in the basis vectors
  #assert result.misindexed_local < result.misindexed_global
  assert result.misindexed_local == 0
  assert result.correct_local > result.correct_global
  # usually the number misindexed is much smaller than this
  assert result.misindexed_local < (0.001 * len(result.reflections_local))

  # the reciprocal matrix
  A = cryst_model.get_A()
  A = random_rotation(angle_max=0.03) * A

  direct_matrix = A.inverse()
  cryst_model2 = crystal_model(direct_matrix[0:3],
                               direct_matrix[3:6],
                               direct_matrix[6:9],
                               space_group=space_group)
  experiment.crystal = cryst_model2

  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)

  # check that the local indexing did a better job given the errors in the basis vectors
  assert result.misindexed_local <= result.misindexed_global
  assert result.misindexed_local < 0.01 * result.correct_local
  assert result.correct_local > result.correct_global
  # usually the number misindexed is much smaller than this
  assert result.misindexed_local < (0.001 * len(result.reflections_local))

class compare_global_local(object):

  def __init__(self, experiment, reflections,
               expected_miller_indices):

    from dials.algorithms.indexing \
         import index_reflections, index_reflections_local
    import copy

    # index reflections using simple "global" method
    self.reflections_global = copy.deepcopy(reflections)
    self.reflections_global['id'] = flex.int(len(self.reflections_global), -1)
    index_reflections(
      self.reflections_global, ExperimentList([experiment]))
    non_zero_sel = (self.reflections_global['miller_index'] != (0,0,0))
    assert self.reflections_global['id'].select(~non_zero_sel).all_eq(-1)
    self.misindexed_global = (
      expected_miller_indices == self.reflections_global['miller_index']).select(
        non_zero_sel).count(False)
    self.correct_global = (
      expected_miller_indices == self.reflections_global['miller_index']).count(True)

    # index reflections using xds-style "local" method
    self.reflections_local = copy.deepcopy(reflections)
    self.reflections_local['id'] = flex.int(len(self.reflections_local), -1)
    index_reflections_local(
      self.reflections_local, ExperimentList([experiment]))
    non_zero_sel = (self.reflections_local['miller_index'] != (0,0,0))
    assert self.reflections_local['id'].select(~non_zero_sel).all_eq(-1)
    self.misindexed_local = (
      expected_miller_indices == self.reflections_local['miller_index']).select(
        non_zero_sel).count(False)
    self.correct_local = (
      expected_miller_indices == self.reflections_local['miller_index']).count(True)

    print self.misindexed_global, self.correct_global, len(self.reflections_global)
    print self.misindexed_local, self.correct_local, len(self.reflections_local)

if __name__ == '__main__':
  from libtbx.utils import show_times_at_exit
  show_times_at_exit()
  from cctbx.sgtbx import bravais_types
  for symbol in bravais_types.acentric:
    space_group_info = sgtbx.space_group_info(symbol=symbol)
    run(space_group_info)
<commit_msg>try a different way of setting the random seed<commit_after>from __future__ import division

import os
import libtbx.load_env
from cctbx import crystal, miller, sgtbx
from scitbx import matrix
from dxtbx.serialize import load
from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList
from dxtbx.model.crystal import crystal_model
from dials.array_family import flex

# set random seeds so tests more reliable
seed = 54321
import random
random.seed(seed)
flex.set_random_seed(seed)

have_dials_regression = libtbx.env.has_module("dials_regression")
if have_dials_regression:
  dials_regression = libtbx.env.find_in_repositories(
    relative_path="dials_regression",
    test=os.path.isdir)

def random_rotation(angle_min=0, angle_max=360):
  import random
  from scitbx.math import euler_angles_as_matrix
  return euler_angles_as_matrix(
    [random.uniform(angle_min,angle_max) for i in xrange(3)])

def run(space_group_info):
  datablock_json = os.path.join(
    dials_regression, "indexing_test_data",
    "i04_weak_data", "datablock_orig.json")

  datablock = load.datablock(datablock_json, check_format=False)[0]
  sweep = datablock.extract_imagesets()[0]

  sweep._indices = sweep._indices[:20]
  sweep.set_scan(sweep.get_scan()[:20])

  import random
  space_group = space_group_info.group()
  unit_cell = space_group_info.any_compatible_unit_cell(volume=random.uniform(1e4,1e6))

  crystal_symmetry = crystal.symmetry(unit_cell=unit_cell,
                                      space_group=space_group)
  crystal_symmetry.show_summary()

  # the reciprocal matrix
  B = matrix.sqr(unit_cell.fractionalization_matrix()).transpose()
  U = random_rotation()
  A = U * B

  direct_matrix = A.inverse()
  cryst_model = crystal_model(direct_matrix[0:3],
                              direct_matrix[3:6],
                              direct_matrix[6:9],
                              space_group=space_group)
  experiment = Experiment(imageset=sweep,
                          beam=sweep.get_beam(),
                          detector=sweep.get_detector(),
                          goniometer=sweep.get_goniometer(),
                          scan=sweep.get_scan(),
                          crystal=cryst_model)
  predicted_reflections = flex.reflection_table.from_predictions(
    experiment)
  use_fraction = 0.3
  use_sel = flex.random_selection(
    len(predicted_reflections), int(use_fraction*len(predicted_reflections)))
  predicted_reflections = predicted_reflections.select(use_sel)
  miller_indices = predicted_reflections['miller_index']
  miller_set = miller.set(
    crystal_symmetry, miller_indices, anomalous_flag=True)
  predicted_reflections['xyzobs.mm.value'] = predicted_reflections['xyzcal.mm']
  predicted_reflections['id'] = flex.size_t(len(predicted_reflections), 0)
  from dials.algorithms.indexing.indexer import indexer_base
  indexer_base.map_centroids_to_reciprocal_space(
    predicted_reflections, sweep.get_detector(), sweep.get_beam(),
    sweep.get_goniometer())

  # check that local and global indexing worked equally well in absence of errors
  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)
  assert result.misindexed_local == 0
  assert result.misindexed_global == 0

  a, b, c = cryst_model.get_real_space_vectors()
  relative_error = 0.02
  a *= (1+relative_error)
  b *= (1+relative_error)
  c *= (1+relative_error)

  cryst_model2 = crystal_model(a, b, c, space_group=space_group)
  experiment.crystal = cryst_model2

  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)

  # check that the local indexing did a better job given the errors in the basis vectors
  #assert result.misindexed_local < result.misindexed_global
  assert result.misindexed_local == 0
  assert result.correct_local > result.correct_global
  # usually the number misindexed is much smaller than this
  assert result.misindexed_local < (0.001 * len(result.reflections_local))

  # the reciprocal matrix
  A = cryst_model.get_A()
  A = random_rotation(angle_max=0.03) * A

  direct_matrix = A.inverse()
  cryst_model2 = crystal_model(direct_matrix[0:3],
                               direct_matrix[3:6],
                               direct_matrix[6:9],
                               space_group=space_group)
  experiment.crystal = cryst_model2

  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)

  # check that the local indexing did a better job given the errors in the basis vectors
  assert result.misindexed_local <= result.misindexed_global, (
    result.misindexed_local, result.misindexed_global)
  assert result.misindexed_local < 0.01 * result.correct_local
  assert result.correct_local > result.correct_global
  # usually the number misindexed is much smaller than this
  assert result.misindexed_local < (0.001 * len(result.reflections_local))

class compare_global_local(object):

  def __init__(self, experiment, reflections,
               expected_miller_indices):

    from dials.algorithms.indexing \
         import index_reflections, index_reflections_local
    import copy

    # index reflections using simple "global" method
    self.reflections_global = copy.deepcopy(reflections)
    self.reflections_global['id'] = flex.int(len(self.reflections_global), -1)
    index_reflections(
      self.reflections_global, ExperimentList([experiment]))
    non_zero_sel = (self.reflections_global['miller_index'] != (0,0,0))
    assert self.reflections_global['id'].select(~non_zero_sel).all_eq(-1)
    self.misindexed_global = (
      expected_miller_indices == self.reflections_global['miller_index']).select(
        non_zero_sel).count(False)
    self.correct_global = (
      expected_miller_indices == self.reflections_global['miller_index']).count(True)

    # index reflections using xds-style "local" method
    self.reflections_local = copy.deepcopy(reflections)
    self.reflections_local['id'] = flex.int(len(self.reflections_local), -1)
    index_reflections_local(
      self.reflections_local, ExperimentList([experiment]))
    non_zero_sel = (self.reflections_local['miller_index'] != (0,0,0))
    assert self.reflections_local['id'].select(~non_zero_sel).all_eq(-1)
    self.misindexed_local = (
      expected_miller_indices == self.reflections_local['miller_index']).select(
        non_zero_sel).count(False)
    self.correct_local = (
      expected_miller_indices == self.reflections_local['miller_index']).count(True)

    print self.misindexed_global, self.correct_global, len(self.reflections_global)
    print self.misindexed_local, self.correct_local, len(self.reflections_local)

if __name__ == '__main__':
  from libtbx.utils import show_times_at_exit
  show_times_at_exit()
  from cctbx.sgtbx import bravais_types
  for symbol in bravais_types.acentric:
    space_group_info = sgtbx.space_group_info(symbol=symbol)
    run(space_group_info)
<|endoftext|>


<commit_before>"""
    Any general purpose utilities useful in the project are defined here.
"""

MW_TIMESTAMP_FORMAT = "%Y%m%d%H%M%S"
from dateutil.parser import parse as date_parse
from collections import namedtuple

def format_mediawiki_timestamp(timestamp_repr):
    """
        Convert representation to mediawiki timestamps.  Returns a sring
         timestamp in the MediaWiki Format.

        Parameters
        ~~~~~~~~~~

        timestamp_repr : str|datetime
           Datetime representation to convert.
    """
    if hasattr(timestamp_repr, 'strftime'):
        return timestamp_repr.strftime(MW_TIMESTAMP_FORMAT)
    else:
        return date_parse(timestamp_repr).strftime(
            MW_TIMESTAMP_FORMAT)

def enum(*sequential, **named):
    """
        Implemetents an enumeration::

            >>> Numbers = enum('ZERO', 'ONE', 'TWO')
            >>> Numbers.ZERO
            0
            >>> Numbers.ONE
            1
    """
    enums = dict(zip(sequential, range(len(sequential))), **named)
    return type('Enum', (), enums)

def build_namedtuple(names, types, values):
    """
        Given a set of types, values, and names builds a named tuple.  This
        method expects three lists all of the same length and returns a
        dynamically built namedtuple object.  Currently, only ``list``,
        ``str``, ``int``, and ``float`` cast methods are accepted as members
        of ``types``.

        Parameters
        ~~~~~~~~~~

        names : list
           Strings representing attribute names.

        types : list
           Typecast methods for each value.

        values : list
           Values of attributes.  These may be string.
    """
    param_type = namedtuple('build_namedtuple', ' '.join(names))
    arg_list = list()
    for t, v in zip(types, values):
        if t == str:
            arg_list.append("'" + str(v) + "'")
        elif t == int or t == list or t == float:
            arg_list.append(str(v))
    return eval('param_type(' + ','.join(arg_list) + ')')

# Rudimentary Testing
if __name__ == '__main__':
    t = build_namedtuple(['a', 'b'], [int, str], [1, 's'])
    print t
<commit_msg>mod. extend build_namedtuple to handle bool types also<commit_after>"""
    Any general purpose utilities useful in the project are defined here.
"""

MW_TIMESTAMP_FORMAT = "%Y%m%d%H%M%S"
from dateutil.parser import parse as date_parse
from collections import namedtuple

def format_mediawiki_timestamp(timestamp_repr):
    """
        Convert representation to mediawiki timestamps.  Returns a sring
         timestamp in the MediaWiki Format.

        Parameters
        ~~~~~~~~~~

        timestamp_repr : str|datetime
           Datetime representation to convert.
    """
    if hasattr(timestamp_repr, 'strftime'):
        return timestamp_repr.strftime(MW_TIMESTAMP_FORMAT)
    else:
        return date_parse(timestamp_repr).strftime(
            MW_TIMESTAMP_FORMAT)

def enum(*sequential, **named):
    """
        Implemetents an enumeration::

            >>> Numbers = enum('ZERO', 'ONE', 'TWO')
            >>> Numbers.ZERO
            0
            >>> Numbers.ONE
            1
    """
    enums = dict(zip(sequential, range(len(sequential))), **named)
    return type('Enum', (), enums)

def build_namedtuple(names, types, values):
    """
        Given a set of types, values, and names builds a named tuple.  This
        method expects three lists all of the same length and returns a
        dynamically built namedtuple object.  Currently, only ``list``,
        ``str``, ``int``, and ``float`` cast methods are accepted as members
        of ``types``.

        Parameters
        ~~~~~~~~~~

        names : list
           Strings representing attribute names.

        types : list
           Typecast methods for each value.

        values : list
           Values of attributes.  These may be string.
    """
    param_type = namedtuple('build_namedtuple', ' '.join(names))

    arg_list = list()
    for t, v in zip(types, values):
        if t == str:
            arg_list.append("'" + str(v) + "'")
        elif t == int or t == list or t == float or t == bool:
            arg_list.append(str(v))

    return eval('param_type(' + ','.join(arg_list) + ')')

# Rudimentary Testing
if __name__ == '__main__':
    t = build_namedtuple(['a', 'b'], [int, str], [1, 's'])
    print t
<|endoftext|>


<commit_before>import logging

from django.core.management import BaseCommand

from corehq.apps.linked_domain.applications import get_downstream_app_id
from corehq.apps.linked_domain.models import DomainLink
from corehq.apps.userreports.dbaccessors import get_report_configs_for_domain
from corehq.apps.userreports.models import DataSourceConfiguration, ReportConfiguration

logger = logging.getLogger('linked_domains')

def migrate_linked_reports(upstream_domain=None):
    logger.setLevel(logging.INFO)
    if upstream_domain:
        domain_links = DomainLink.objects.filter(master_domain=upstream_domain)
    else:
        domain_links = DomainLink.objects.all()

    num_of_failed_attempts = 0
    for domain_link in domain_links:
        reports = get_report_configs_for_domain(domain_link.linked_domain)
        for report in reports:
            if report.report_meta.master_id and not report.config.meta.build.app_id:
                upstream_report = ReportConfiguration.get(report.report_meta.master_id)
                upstream_datasource = DataSourceConfiguration.get(upstream_report.config_id)
                downstream_app_id = get_downstream_app_id(
                    domain_link.linked_domain,
                    upstream_datasource.meta.build.app_id,
                )
                if not downstream_app_id:
                    # just as a backup in case upstream_app_id is not set but family_id is
                    downstream_app_id = get_downstream_app_id(
                        domain_link.linked_domain,
                        upstream_datasource.meta.build.app_id,
                        use_upstream_app_id=False
                    )
                if not downstream_app_id:
                    logger.warning(f"Could not find downstream_app_id for upstream app"
                                   f" {upstream_datasource.meta.build.app_id} "
                                   f"in downstream domain {domain_link.linked_domain}")
                    num_of_failed_attempts += 1

                report.config.meta.build.app_id = downstream_app_id
                report.config.save()
    logger.info(f"Completed linked report migration with {num_of_failed_attempts} failed attempts")
    return num_of_failed_attempts

class Command(BaseCommand):
    """
    Searches for existing linked reports that do not contain an app_id, and adds the app_id
    """

    def add_arguments(self, parser):
        parser.add_argument('upstream_domain', nargs='?')

    def handle(self, upstream_domain, **options):
        migrate_linked_reports(upstream_domain)
<commit_msg>add helpful log when using family_id<commit_after>import logging

from django.core.management import BaseCommand

from corehq.apps.linked_domain.applications import get_downstream_app_id
from corehq.apps.linked_domain.models import DomainLink
from corehq.apps.userreports.dbaccessors import get_report_configs_for_domain
from corehq.apps.userreports.models import DataSourceConfiguration, ReportConfiguration

logger = logging.getLogger('linked_domains')

def migrate_linked_reports(upstream_domain=None):
    logger.setLevel(logging.INFO)
    if upstream_domain:
        domain_links = DomainLink.objects.filter(master_domain=upstream_domain)
    else:
        domain_links = DomainLink.objects.all()

    num_of_failed_attempts = 0
    for domain_link in domain_links:
        reports = get_report_configs_for_domain(domain_link.linked_domain)
        for report in reports:
            if report.report_meta.master_id and not report.config.meta.build.app_id:
                upstream_report = ReportConfiguration.get(report.report_meta.master_id)
                upstream_datasource = DataSourceConfiguration.get(upstream_report.config_id)
                downstream_app_id = get_downstream_app_id(
                    domain_link.linked_domain,
                    upstream_datasource.meta.build.app_id,
                )
                if not downstream_app_id:
                    # just as a backup in case upstream_app_id is not set but family_id is
                    downstream_app_id = get_downstream_app_id(
                        domain_link.linked_domain,
                        upstream_datasource.meta.build.app_id,
                        use_upstream_app_id=False
                    )
                    if downstream_app_id:
                        logger.info(f"Needed to use family_id to find downstream app {downstream_app_id}")

                if not downstream_app_id:
                    logger.warning(f"Could not find downstream_app_id for upstream app"
                                   f" {upstream_datasource.meta.build.app_id} "
                                   f"in downstream domain {domain_link.linked_domain}")
                    num_of_failed_attempts += 1

                report.config.meta.build.app_id = downstream_app_id
                report.config.save()
    logger.info(f"Completed linked report migration with {num_of_failed_attempts} failed attempts")
    return num_of_failed_attempts

class Command(BaseCommand):
    """
    Searches for existing linked reports that do not contain an app_id, and adds the app_id
    """

    def add_arguments(self, parser):
        parser.add_argument('upstream_domain', nargs='?')

    def handle(self, upstream_domain, **options):
        migrate_linked_reports(upstream_domain)
<|endoftext|>


<commit_before>#!/usr/bin/python2.5
#
# Copyright 2010 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""GSOC module cleaning methods.
"""

__authors__ = [
    '"Daniel Hans" <daniel.m.hans@gmail.com>',
    ]

import re

from django import forms
from django.utils.translation import ugettext

from soc.logic import cleaning

def cleanTagsList(field_name):
  """Clean method to check and validate list of tag values.
  """

  def wrapper(self):
    """Decorator wrapped method.
    """

    tag_values = cleaning.str2set(field_name, '\n')(self)

    for index, tag_value in enumerate(tag_values):

      if not re.search('\A[a-zA-Z0-9_#+\-\.]*\Z', tag_value):
        raise forms.ValidationError(ugettext(
            ('%s is not a valid tag value. Please see help for more details.'
            % tag_value)))

      tag_values[index] = tag_value.lower()

    return tag_values
  return wrapper
<commit_msg>a-zA-Z0-9_ pattern changed to \w.<commit_after>#!/usr/bin/python2.5
#
# Copyright 2010 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""GSOC module cleaning methods.
"""

__authors__ = [
    '"Daniel Hans" <daniel.m.hans@gmail.com>',
    ]

import re

from django import forms
from django.utils.translation import ugettext

from soc.logic import cleaning

def cleanTagsList(field_name):
  """Clean method to check and validate list of tag values.
  """

  def wrapper(self):
    """Decorator wrapped method.
    """

    tag_values = cleaning.str2set(field_name, '\n')(self)

    for index, tag_value in enumerate(tag_values):

      if not re.search('\A[\w#+\-\.]*\Z', tag_value):
        raise forms.ValidationError(ugettext(
            ('%s is not a valid tag value. Please see help for more details.'
            % tag_value)))

      tag_values[index] = tag_value.lower()

    return tag_values
  return wrapper
<|endoftext|>


<commit_before>#!/usr/bin/env python2.5
#
# Copyright 2011 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This module contains the GSoCProject Model.
"""

from google.appengine.ext import db

from django.utils.translation import ugettext

from soc.modules.gsoc.models.code_sample import GSoCCodeSample
from soc.modules.gsoc.models.profile import GSoCProfile

import soc.modules.gsoc.models.proposal
import soc.models.program
import soc.models.organization

class GSoCProject(db.Model):
  """Model for a GSoC project used in the GSoC workflow.

  Parent:
    soc.modules.gsoc.models.profile.Profile
  """

  #: Required field indicating the "title" of the project
  title = db.StringProperty(required=True,
      verbose_name=ugettext('Title'))
  title.help_text = ugettext('Title of the project')

  #: Required, text field describing the project
  abstract = db.TextProperty(
      required=True, verbose_name=ugettext('Project abstract'))
  abstract.help_text = ugettext(
      'Short abstract, summary, or snippet;'
      ' 500 characters or less, plain text displayed publicly')

  #: Optional, text field containing all kinds of information about this project
  public_info = db.TextProperty(
      required=False, default ='',
      verbose_name=ugettext('Additional information'))
  public_info.help_text = ugettext(
      'Additional information about this project to be shown publicly')

  #: Optional, URL which can give more information about this project
  additional_info = db.URLProperty(
      required=False, verbose_name=ugettext('External resource URL'))
  additional_info.help_text = ugettext(
      'Link to a resource containing more information about this project.')

  #: Optional field storing a feed URL; displayed publicly
  feed_url = db.LinkProperty(
      verbose_name=ugettext('Project Feed URL'))
  feed_url.help_text = ugettext(
      'The URL should be a valid ATOM or RSS feed. '
      'Feed entries are shown on the public page.')

  #: The project can be marked to be featured on program home page.
  is_featured = db.BooleanProperty(default=False, required=True,
                                   verbose_name=ugettext('Featured'))
  is_featured.help_text = ugettext(
      'Should this project be featured on the program homepage.')

  #: A property containing a list of Mentors assigned for this project
  mentors = db.ListProperty(item_type=db.Key, default=[], required=True)

  def getMentors(self):
    """Returns a list of GSoCProfile entities which
    are mentors for this project.
    """
    return [m for m in GSoCProfile.get(self.mentors) if m]

  #: The status of this project
  #: accepted: This project has been accepted into the program
  #: failed: This project has failed an evaluation.
  #: completed: (DEPRECATED) This project has completed the program
  #:            successfully. This should be set automatically when a program
  #:            has been deemed finished. This status is the same as accepted
  #:            when len(passed_evaluations) == 2.
  #: withdrawn: This project has been withdrawn from the program by a Program
  #:            Administrator or higher.
  #: invalid: This project has been marked as invalid because it was deleted
  status = db.StringProperty(
      required=True, default='accepted',
      choices=['accepted', 'failed', 'completed', 'withdrawn', 'invalid'])

  #: List of all processed GradingRecords which state a pass for this project.
  #: This property can be used to determine how many evaluations someone has
  #: passed. And is also used to ensure that a GradingRecord has been
  #: processed.
  passed_evaluations = db.ListProperty(item_type=db.Key, default=[])

  #: List of all processed GradingRecords which state a fail for this project.
  #: This is a ListProperty to ensure that the system keeps functioning when
  #: manual changes in GradingRecords occur.
  failed_evaluations = db.ListProperty(item_type=db.Key, default=[])

  #: Organization which this project is in
  org = db.ReferenceProperty(
      reference_class=soc.models.organization.Organization,
      required=True, collection_name='student_projects')

  #: Program in which this project has been created
  program = db.ReferenceProperty(reference_class=soc.models.program.Program,
                                 required=True,
                                 collection_name='projects')

  #: Proposal to which this project corresponds to
  proposal = db.ReferenceProperty(
      reference_class=soc.modules.gsoc.models.proposal.GSoCProposal,
      required=False,
      collection_name='projects')

  #: Whether the student has submitted their code samples or not
  code_samples_submitted = db.BooleanProperty(default=False)

  def codeSamples(self):
    """Returns GSoCCodeSample entities uploaded for this project.
    """
    query = GSoCCodeSample.all()
    query.ancestor(self)
    return query.fetch(1000)

  def countCodeSamples(self):
    """Returns number of GSoCCodeSample entities uploaded for this project.
    """
    query = GSoCCodeSample.all(keys_only=True)
    query.ancestor(self)
    return query.count()
<commit_msg>Removing completed status from the GSoCProject model.<commit_after>#!/usr/bin/env python2.5
#
# Copyright 2011 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This module contains the GSoCProject Model.
"""

from google.appengine.ext import db

from django.utils.translation import ugettext

from soc.modules.gsoc.models.code_sample import GSoCCodeSample
from soc.modules.gsoc.models.profile import GSoCProfile

import soc.modules.gsoc.models.proposal
import soc.models.program
import soc.models.organization

class GSoCProject(db.Model):
  """Model for a GSoC project used in the GSoC workflow.

  Parent:
    soc.modules.gsoc.models.profile.Profile
  """

  #: Required field indicating the "title" of the project
  title = db.StringProperty(required=True,
      verbose_name=ugettext('Title'))
  title.help_text = ugettext('Title of the project')

  #: Required, text field describing the project
  abstract = db.TextProperty(
      required=True, verbose_name=ugettext('Project abstract'))
  abstract.help_text = ugettext(
      'Short abstract, summary, or snippet;'
      ' 500 characters or less, plain text displayed publicly')

  #: Optional, text field containing all kinds of information about this project
  public_info = db.TextProperty(
      required=False, default ='',
      verbose_name=ugettext('Additional information'))
  public_info.help_text = ugettext(
      'Additional information about this project to be shown publicly')

  #: Optional, URL which can give more information about this project
  additional_info = db.URLProperty(
      required=False, verbose_name=ugettext('External resource URL'))
  additional_info.help_text = ugettext(
      'Link to a resource containing more information about this project.')

  #: Optional field storing a feed URL; displayed publicly
  feed_url = db.LinkProperty(
      verbose_name=ugettext('Project Feed URL'))
  feed_url.help_text = ugettext(
      'The URL should be a valid ATOM or RSS feed. '
      'Feed entries are shown on the public page.')

  #: The project can be marked to be featured on program home page.
  is_featured = db.BooleanProperty(default=False, required=True,
                                   verbose_name=ugettext('Featured'))
  is_featured.help_text = ugettext(
      'Should this project be featured on the program homepage.')

  #: A property containing a list of Mentors assigned for this project
  mentors = db.ListProperty(item_type=db.Key, default=[], required=True)

  def getMentors(self):
    """Returns a list of GSoCProfile entities which
    are mentors for this project.
    """
    return [m for m in GSoCProfile.get(self.mentors) if m]

  #: The status of this project
  #: accepted: This project has been accepted into the program
  #: failed: This project has failed an evaluation.
  #: withdrawn: This project has been withdrawn from the program by a Program
  #:            Administrator or higher.
  #: invalid: This project has been marked as invalid because it was deleted
  status = db.StringProperty(
      required=True, default='accepted',
      choices=['accepted', 'failed', 'withdrawn', 'invalid'])

  #: List of all processed GradingRecords which state a pass for this project.
  #: This property can be used to determine how many evaluations someone has
  #: passed. And is also used to ensure that a GradingRecord has been
  #: processed.
  passed_evaluations = db.ListProperty(item_type=db.Key, default=[])

  #: List of all processed GradingRecords which state a fail for this project.
  #: This is a ListProperty to ensure that the system keeps functioning when
  #: manual changes in GradingRecords occur.
  failed_evaluations = db.ListProperty(item_type=db.Key, default=[])

  #: Organization which this project is in
  org = db.ReferenceProperty(
      reference_class=soc.models.organization.Organization,
      required=True, collection_name='student_projects')

  #: Program in which this project has been created
  program = db.ReferenceProperty(reference_class=soc.models.program.Program,
                                 required=True,
                                 collection_name='projects')

  #: Proposal to which this project corresponds to
  proposal = db.ReferenceProperty(
      reference_class=soc.modules.gsoc.models.proposal.GSoCProposal,
      required=False,
      collection_name='projects')

  #: Whether the student has submitted their code samples or not
  code_samples_submitted = db.BooleanProperty(default=False)

  def codeSamples(self):
    """Returns GSoCCodeSample entities uploaded for this project.
    """
    query = GSoCCodeSample.all()
    query.ancestor(self)
    return query.fetch(1000)

  def countCodeSamples(self):
    """Returns number of GSoCCodeSample entities uploaded for this project.
    """
    query = GSoCCodeSample.all(keys_only=True)
    query.ancestor(self)
    return query.count()
<|endoftext|>