def test_update(self):
        ini_service = InitialService()
        conn = ini_service.get_connection()

        instance_service = InstanceService(conn)
        try:
            instance_service.insert("Stroke Annotation-update1", "CT", "Stroke annotation descriptions.",
                                    "./data/stroke_instance-update1", 0, 50, 10, 0)
        except Error:
            pass

        last_rowid = instance_service.query({"name": "Stroke Annotation-update1"})[0]["instance_id"]

        labelcandidates_service = LabelCandidatesService(conn)
        labelcandidates_service.insert(last_rowid, 0, None, "Ischemic Stroke-update1")

        status = labelcandidates_service.update({"instance_id": last_rowid},
                                                {"text": "Ischemic Stroke-update2", "label_type": 1})
        update_item = labelcandidates_service.query({"instance_id": last_rowid})
        assert status is True
        assert update_item[0]["text"] == "Ischemic Stroke-update2"

        status = labelcandidates_service.update({"instance_id": 1000},
                                                {"text": "Ischemic Stroke-update2", "label_type": 1})
        assert status is False
    def test_delete(self):
        ini_service = InitialService()
        conn = ini_service.get_connection()

        instance_service = InstanceService(conn)
        # In case the record doesn't exist.
        try:
            instance_service.insert("Stroke Annotation-del1", "CT", "Stroke annotation descriptions.",
                                    "./data/stroke_instance-del1", 0, 50, 10, 0)
        except Error:
            pass

        last_rowid = instance_service.query({"name": "Stroke Annotation-del1"})[0]["instance_id"]

        labelcandidates_service = LabelCandidatesService(conn)
        labelcandidates_service.insert(last_rowid, 0, None, "Ischemic Stroke")
        candidate_id = labelcandidates_service.query({"text": "Ischemic Stroke", "instance_id": last_rowid})[0][
            "candidate_id"]

        status = labelcandidates_service.delete({"candidate_id": candidate_id})
        assert status is True

        labelcandidates_service.insert(last_rowid, 0, None, "Ischemic Stroke")
        candidate_id = labelcandidates_service.query({"text": "Ischemic Stroke", "instance_id": last_rowid})

        status = labelcandidates_service.delete({"text": "Ischemic Stroke", "instance_id": last_rowid})
        assert status is True

        status = labelcandidates_service.delete({"text": "Ischemic Stroke", "instance_id": last_rowid})
        assert status is False
    def test_create(self):
        ini_service = InitialService()
        conn = ini_service.get_connection()

        labelcandidates_service = LabelCandidatesService(conn)

        insert_status = labelcandidates_service.insert(1, 0, None, "Ischemic Stroke")

        assert insert_status is False

        instance_service = InstanceService(conn)
        instance_service.insert("Stroke annotation", "CT", "description...", "./data/stroke_data", 0, 100, 10, 0)
        last_rowid = instance_service.query({"name": "Stroke annotation"})[0]["instance_id"]

        insert_rowid = labelcandidates_service.insert(last_rowid, 0, None, "Ischemic Stroke")
        assert insert_rowid == 1
    def test_query_one_record(self):
        ini_service = InitialService()
        conn = ini_service.get_connection()
        instance_service = InstanceService(conn)

        labelcandidates_service = LabelCandidatesService(conn)
        # In case the record doesn't exist.
        try:
            instance_service.insert("Stroke annotation", "CT", "Stroke annotation descriptions.",
                                    "./data/stroke_data", 0, 50, 10, 0)
        except Error:
            print(Error)
            pass
        last_rowid = instance_service.query({"name": "Stroke annotation"})[0]["instance_id"]
        labelcandidates_service.insert(last_rowid, 0, None, "Ischemic Stroke")
        result = labelcandidates_service.query({"instance_id": last_rowid})
        assert result[0]["text"] == "Ischemic Stroke"
示例#5
0
    def test_instance_detail_delete(self, client):
        ini_service = InitialService()
        conn = ini_service.get_connection()

        instance_service = InstanceService(conn)
        instance_id = instance_service.insert(
            "Stroke Annotation Task2", "CT",
            "The stroke CT scans for annotation tasks.",
            "tests/services/sample_data", 0, 200, 1, 0)

        res = client.delete(url_for('instance_detail',
                                    instance_id=instance_id))
        assert res.json == {}
        assert res.status == "200 OK"

        res = client.delete(url_for('instance_detail',
                                    instance_id=instance_id))
        assert res.json == {}
        assert res.status == "404 NOT FOUND"
示例#6
0
    def test_list_all_studies(self, client):
        res = client.get(url_for('list_all_studies', instance_id=1))
        assert res.json == {}
        assert res.status == '200 OK'

        # Setup studies sample data
        ini_service = InitialService()
        conn = ini_service.get_connection()
        instance_service = InstanceService(conn)
        instance_service.insert("Stroke Annotation Task", "CT",
                                "The stroke CT scans for annotation tasks.",
                                "tests/services/sample_data", 0, 200, 1, 0)
        result = instance_service.query({})
        assert result[0]["instance_id"] == 1
        assert result[0]["name"] == "Stroke Annotation Task"

        studies_service = StudiesService(conn)
        studies_service.insert(1, "Dicom_691_2", 25, 0, "folder", 100, 1)
        studies_service.insert(1, "Raw_1003/3CH_tagging", 30, 1, "folder", 100,
                               1)

        series_service = SeriesService(conn)
        series_service.insert(1, "series1", "series1/path", ["1"], 1, "200",
                              "200", "0.5", "0.5", "0.5", 512, 512, 512, 1,
                              100101, "", "", "")
        series_service.insert(1, "series2", "series2/path", ["1"], 1, "200",
                              "200", "0.5", "0.5", "0.5", 512, 512, 512, 1,
                              100101, "", "", "")
        series_service.insert(2, "series3", "series3/path", ["1"], 1, "200",
                              "200", "0.5", "0.5", "0.5", 512, 512, 512, 1,
                              100101, "", "", "")
        series_service.insert(2, "series4", "series4/path", ["1"], 1, "200",
                              "200", "0.5", "0.5", "0.5", 512, 512, 512, 1,
                              100101, "", "", "")

        res = client.get(url_for('list_all_studies', instance_id=1))
        assert len(res.json[0]) == 2
        assert res.json[0][0]["instance_id"] == 1
        assert res.json[0][0]["patient_uid"] == "Dicom_691_2"
        assert res.json[1][0]["instance_id"] == 1
        assert res.json[1][0]["patient_uid"] == "Raw_1003/3CH_tagging"
        assert res.status == '200 OK'
示例#7
0
    def add_labels(series_id, file_name):
        # Temporary mock the user Id.
        user_id = 1
        data = request.data
        label_service = LabelService(get_conn())
        status = label_service.insert(series_id, user_id, file_name, data)

        update_status = request.args.get('update_status',
                                         type=bool,
                                         default=False)
        if update_status:
            series_service = SeriesService(get_conn())
            study_service = StudiesService(get_conn())
            instance_service = InstanceService(get_conn())
            series = series_service.query({'series_id': series_id})
            if len(series) > 0:
                study_id = series[0]['study_id']
                status = series[0]['status']
                if status < SERIES_STATUS.annotating.value:
                    series_service.update(
                        {'series_id': series_id},
                        {'status': SERIES_STATUS.annotating.value})
                study = study_service.query({'study_id': study_id})
                instance_id = study[0]['instance_id']
                if study[0]['status'] != STUDY_STATUS.annotating.value:
                    study_service.update(
                        {'study_id': study_id},
                        {'status': STUDY_STATUS.annotating.value})
                instance = instance_service.query({'instance_id': instance_id})
                if instance[0]['status'] != INSTANCE_STATUS.annotating.value:
                    instance_service.update(
                        {'instance_id': instance_id},
                        {'status': INSTANCE_STATUS.annotating.value})

        if status:
            return jsonify({}), 201
        else:
            return jsonify({status: "Transaction Rollback."}), 404
示例#8
0
    def insert(self, instance_id, label_type, input_type, text, contour_label_value=-1):
        """
        Insert new record for LabelCandidates.
        :param instance_id:
        :param label_type:
        :param input_type:
        :param text:
        :param contour_label_value: id for contour label. -1 for default self-increasing id.
        :return:
        """

        instance_service = InstanceService(self.sql_connection)

        if len(instance_service.query({"instance_id": instance_id})) == 0:
            # There is no such instance ID.
            return False

        cur = self.sql_connection.cursor()
        sql, v = prepare_insert("label_candidates",
                                {"instance_id": instance_id, "label_type": label_type, "input_type": input_type,
                                 "text": text, "contour_label_value": contour_label_value})
        cur.execute(sql, v)
        self.sql_connection.commit()
        return cur.lastrowid
示例#9
0
    def instance_list():

        instance_service = InstanceService(get_conn())
        label_candidates_service = LabelCandidatesService(get_conn())
        if request.method == "GET":
            instances = instance_service.query({})
            return jsonify(instances), 200
        elif request.method == "POST":
            data = json.loads(request.data)
            name = data.get("name", "New instance")
            modality = data.get("modality", "CT")
            description = data.get("description", "")
            data_path = ""  # Set the data_path as default now.
            has_audit = False
            annotator_id = list(
                filter(None, str.split(data.get("annotator_id", ""), "|")))
            auditor_id = list(
                filter(None, str.split(data.get("auditor_id", ""), "|")))
            label_candidates = data.get("label_candidates", [])

            instance_id = instance_service.insert(name, modality, description,
                                                  data_path, has_audit, 0, 0,
                                                  INSTANCE_STATUS.init.value)
            if instance_id == -1:
                # Instance name already exist.
                return jsonify({"err": "Instance Name exist"}), 409
            for user_id in annotator_id:
                instance_service.insert_user_in_instance(
                    instance_id, user_id, False)
            for user_id in auditor_id:
                instance_service.insert_user_in_instance(
                    instance_id, user_id, True)
            for label in label_candidates:
                label_type = int(label['label_type'])
                input_type = int(label['input_type'])
                text = label['text']
                contour_label_value = label['contour_label_value']
                label_candidates_service.insert(instance_id, label_type,
                                                input_type, text,
                                                contour_label_value)

            return jsonify({"instance_id": instance_id}), 201
示例#10
0
    def import_dcm(self, instance_id, data_path):

        instance_service = InstanceService(self.conn)
        instance_service.update({'instance_id': instance_id}, {'status': INSTANCE_STATUS.importing_dicom.value})
        series_extraction_service = SeriesExtractionService()
        all_series_list = series_extraction_service.extract_series_from_path(os.path.join(DATA_ROOT, data_path))
        study_service = StudiesService(self.conn)
        series_service = SeriesService(self.conn)

        for suid in all_series_list:
            series = all_series_list[suid]
            patient_uid = 0
            study_uid = 0
            study_service.insert(instance_id, patient_uid, study_uid, suid, "[]", 0, 0)
            study = study_service.query({"instance_id": instance_id, "suid": suid})
            study = study[0]
            total_files_number = 0
            folder_name_arr = []
            for series_path in series:
                folder_name_arr.append(series_path)
                one_series = series[series_path][0]
                patient_uid = one_series.info.PatientID
                study_uid = one_series.info.StudyID
                if patient_uid == "" or study_uid == "":
                    patient_uid = ""
                    study_uid = suid
                # disp_name = "pid:" + one_series.info.PatientID + "_sid:" + one_series.info.StudyID
                total_files_number += one_series.length
                series_info = one_series.info
                if len(one_series.shape) == 2:
                    z_dim = 1
                    x_dim = one_series.shape[0]
                    y_dim = one_series.shape[1]
                else:
                    z_dim = one_series.shape[0]
                    x_dim = one_series.shape[1]
                    y_dim = one_series.shape[2]

                series_service.insert(study['study_id'], one_series.description, series_path, one_series.filenames,
                                      one_series.length, series_info.get("WindowWidth"),
                                      series_info.get("WindowCenter"), one_series.sampling[1], one_series.sampling[1],
                                      one_series.sampling[0], x_dim, y_dim, z_dim, series_info.get("PatientID"),
                                      series_info.get("SeriesInstanceUID"), series_info.get("StudyDate") or "", "",
                                      "", SERIES_STATUS.init.value)

            study_service.update({"instance_id": instance_id, "suid": suid},
                                 {"total_files_number": total_files_number, "patient_uid": patient_uid,
                                  "study_uid": study_uid, "folder_name": str(folder_name_arr),
                                  "status": STUDY_STATUS.ready_to_annotate.value})

        instance_service.update({'instance_id': instance_id}, {'status': INSTANCE_STATUS.ready_to_annotate.value})
        return True
示例#11
0
    def instance_detail(instance_id):
        """
        [POST]  /instance/<instance_id>
        name, modality, description, annotator_ids(split by vbar), auditor_ids,
        label_candidates:
        :return:
        """
        instance_service = InstanceService(get_conn())
        label_candidates_service = LabelCandidatesService(get_conn())
        if request.method == "GET":
            instance_info = instance_service.query(
                {"instance_id": instance_id})
            if len(instance_info) == 0:
                return jsonify({}), 200
            label_candidate_service = LabelCandidatesService(get_conn())
            label_candidates = label_candidate_service.query(
                {"instance_id": instance_id})

            json_result = instance_info[0]
            json_result['label_candidates'] = label_candidates

            return jsonify(json_result), 200
        elif request.method == "DELETE":
            status = instance_service.delete({"instance_id": instance_id})
            instance_service.delete_all_users_in_instance(instance_id)
            label_candidates_service.delete({"instance_id": instance_id})
            if status:
                return jsonify({}), 200
            else:
                return jsonify({}), 404
        elif request.method == "PUT":

            instance_info = instance_service.query(
                {"instance_id": instance_id})
            if len(instance_info) == 0:
                return jsonify({}), 200

            data = json.loads(request.data)
            name = data.get("name", "New instance")
            modality = data.get("modality", "CT")
            description = data.get("description", "")
            # data_path = ""  # Set the data_path as default now.
            has_audit = False
            annotator_id = list(
                filter(None, str.split(data.get("annotator_id", ""), "|")))
            auditor_id = list(
                filter(None, str.split(data.get("auditor_id", ""), "|")))
            label_candidates = data.get("label_candidates", [])

            instance_service.update({"instance_id": instance_id}, {
                "name": name,
                "modality": modality,
                "description": description,
                "has_audit": has_audit
            })

            instance_service.delete_all_users_in_instance(instance_id)
            for user_id in annotator_id:
                instance_service.insert_user_in_instance(
                    instance_id, user_id, False)
            for user_id in auditor_id:
                instance_service.insert_user_in_instance(
                    instance_id, user_id, True)

            # Delete all label candidates for current instance and add again.
            label_candidates_service.delete({"instance_id": instance_id})
            for label in label_candidates:
                label_type = int(label['label_type'])
                input_type = int(label['input_type'])
                text = label['text']
                contour_label_value = label['contour_label_value']
                label_candidates_service.insert(instance_id, label_type,
                                                input_type, text,
                                                contour_label_value)

            return jsonify({"instance_id": instance_id}), 201
示例#12
0
    def save_studies(self,
                     instance_id,
                     split_entry_num=100,
                     start_idx=0,
                     end_idx=-1,
                     store_type="train",
                     save_pair=True,
                     save_label=True,
                     save_data=True,
                     compression=None):
        """
        Save all annotations and and dicom data for each study in the instance.
        :param instance_id:
        :param split_entry_num: create new h5 file if stored entries more than the max split number
        :param start_idx: start file number.
        :param end_idx: end of the file number.
        :param store_type: train or test
        :param save_pair: True or False. If save the pair, will only save the series which have labels.
        :param save_label: True or False
        :param save_data: True or False
        :param compression: Whether the hdf5 file compressed or not. "gzip|lzf"
        :return:
        """
        msg_box = []
        instance_service = InstanceService(self.conn)
        instance = instance_service.query({"instance_id": instance_id})
        instance_name = instance[0]['name']
        study_service = StudiesService(self.conn)
        studies = study_service.query({"instance_id": instance_id})
        study_num = split_entry_num * start_idx
        if end_idx == -1:
            end_num = len(studies)
        else:
            end_num = split_entry_num * end_idx

        study_h5 = None
        time_stamp = str(int(time.time()))
        for idx, study in enumerate(studies):
            if idx == study_num and idx < end_num:
                study_id = study['study_id']
                app.logger.info(
                    f"Save study-instance_id:{instance_id}({instance_name}),study_id:{study_id}"
                )
                h5_path = os.path.join(OUTPUT_ROOT, str(instance_id))
                if study_num % split_entry_num == 0:
                    if not os.path.exists(h5_path):
                        os.makedirs(h5_path)
                    if study_h5 is not None:
                        study_h5.close()
                    h5_file_name = f"Export-{instance_id}-{instance_name}-{time_stamp}-{study_num // split_entry_num}.h5"
                    study_h5 = h5py.File(os.path.join(h5_path, h5_file_name),
                                         'w')

                if save_pair:
                    _, saved_label, _ = self.save_onestudy_label(
                        study_id, study, study_h5, msg_box, store_type,
                        compression)
                    self.save_onestudy_dcm(study_id, study, study_h5, msg_box,
                                           store_type, compression,
                                           saved_label)

                else:
                    if save_label:
                        self.save_onestudy_label(study_id, study, study_h5,
                                                 msg_box, store_type,
                                                 compression)

                    if save_data:
                        self.save_onestudy_dcm(study_id, study, study_h5,
                                               msg_box, store_type,
                                               compression)

                study_num += 1

        study_h5.close()
        return msg_box