class Series(db.Model): __tablename__ = 'series' id = db.Column(db.Integer, primary_key=True) work_item_id = db.Column(db.Integer, db.ForeignKey('work_items.id')) uid = db.Column(db.String, index=True) # Series Instance UID plane = db.Column(db.String, db.Enum('axial', 'sagittal', 'coronal')) created_on = db.Column(db.DateTime, server_default=db.func.now(), index=True) updated_on = db.Column(db.DateTime, server_default=db.func.now(), onupdate=db.func.now()) massive_bleeding = db.Column(db.Boolean, default=False) findings = db.relationship('Finding', order_by='Finding.order') def __repr__(self): return "<Series(uid='{}', plane='{}', massive_bleeding={})>".format( self.uid, self.plane, self.massive_bleeding) def to_json_dict(self): return { 'uid': self.uid, 'plane': self.plane, 'massiveBleeding': self.massive_bleeding }
class StaticData(db.Model): __tablename__ = 'static_data' id = db.Column(db.Integer, primary_key = True) host_name = db.Column(db.String(255)) device_type = db.Column(db.String(255)) operating_system = db.Column(db.String(255)) mac_address = db.Column(db.String(255), unique=True) ip_address = db.Column(db.String(255)) snap_shots = db.relationship('DynamicData', back_populates='static_data')
class DynamicData(db.Model): __tablename__ = 'dynamic_data' id = db.Column(db.Integer, primary_key = True) static_data_id = db.Column(db.Integer, db.ForeignKey('static_data.id'), nullable=False) static_data = db.relationship('StaticData', back_populates='snap_shots') time_stamp = db.Column(db.String(255)) upload_speed = db.Column(db.Integer) download_speed = db.Column(db.Integer) active_connection = db.Column(db.Boolean)
class UserModel(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(32), index=True) name = db.Column(db.String(32)) password_hash = db.Column(db.String(64)) email = db.Column(db.String(50)) address = db.Column(db.String(100)) cellphone = db.Column(db.String(15)) permission = db.Column(db.Integer, default=0) order = db.relationship('OrderModel') def hash_password(self, password): self.password_hash = pwd_context.encrypt(password) def verify_password(self, password): return pwd_context.verify(password, self.password_hash)
class Authors(db.Model): __tablename__ = 'authors' id = db.Column(db.Integer, primary_key=True, autoincrement=True) first_name = db.Column(db.String(20)) last_name = db.Column(db.String(20)) created = db.Column(db.DateTime, server_default=db.func.now()) books = db.relationship('Book', backref='Authors', cascade="all, delete-orphan") def __init__(self, first_name, last_name, books=[]): self.first_name = first_name self.last_name = last_name self.books = books def create(self): db.session.add(self) db.session.commit() return self
class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True) name = db.Column(db.String(80)) password = db.Column(Password) role = db.Column(db.String(20), server_default='user', nullable=False) email = db.Column(db.String(120)) load_finding_files = db.Column(Boolean, server_default='1', nullable=False) created_on = db.Column(db.DateTime) last_login_on = db.Column(db.DateTime) last_login_from = db.Column(db.String(80)) worklist = db.relationship('WorkItem', order_by='WorkItem.id') def __init__(self, username, name, password, created_on, email, role='user', load_finding_files=True): self.username = username self.name = name self.password = password self.role = role self.email = email self.created_on = created_on self.load_finding_files = load_finding_files def __repr__(self): return "<User(username='******', name='%s')>" % (self.username, self.name) @validates('password') def _validate_password(self, key, password): return getattr(type(self), key).type.validator(password) @property def is_admin(self): return self.role == 'admin' def to_json_dict(self): last_login = "******" if self.last_login_on is None else self.last_login_on.strftime( '%Y-%m-%d') created_on = "Not Available" if self.created_on is None else self.created_on.strftime( '%Y-%m-%d') last_login_from = "Not Available" if self.last_login_from is None else self.last_login_from email = "" if self.email is None else self.email load_finding_files = self.load_finding_files return { 'id': self.id, 'username': self.username, 'name': self.name, 'role': self.role, 'created_on': created_on, 'last_login_on': last_login, 'email': email, 'last_login_from': last_login_from, 'load_finding_files': load_finding_files }
class WorkItem(db.Model): __tablename__ = 'work_items' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) uid = db.Column(db.String) # Study Instance UID accession_number = db.Column(db.String, index=True) patient_name = db.Column(db.String) patient_id = db.Column(db.String) study_date = db.Column(db.String) study_time = db.Column(db.String) body_part = db.Column(db.String, db.Enum(*DEFAULT_WINDOW_DEFS.keys())) status = db.Column(db.String) finalized_as = db.Column(db.String, db.Enum('positive', 'negative')) created_on = db.Column(db.DateTime, server_default=db.func.now()) updated_on = db.Column(db.DateTime, server_default=db.func.now(), onupdate=db.func.now()) comment = db.Column(db.String) massive_bleeding = db.Column(db.Boolean, default=False) favorite = db.Column(db.Boolean, default=False) analyzed_by_aidoc = db.Column(db.Boolean, default=False) location = db.Column(db.String, db.Enum(*patientLocations)) order_by = db.Column(db.Integer) series = db.relationship('Series', order_by='Series.created_on') findings = db.relationship('Finding', order_by='Finding.order') db.UniqueConstraint('user_id', 'uid', name='user_work_item_uq') def __init__(self, user_id, uid, accession_number, patient_name, patient_id, study_date, study_time, body_part, status='pending', analyzed_by_aidoc=True): self.user_id = user_id self.uid = uid self.accession_number = accession_number self.patient_name = patient_name self.patient_id = patient_id self.study_date = study_date self.study_time = study_time self.body_part = body_part self.status = status self.analyzed_by_aidoc = analyzed_by_aidoc def __repr__(self): return "<WorkItem(uid='%s', accession_number='%s', patient_name='%s', body_part='%s', status='%s')>" %\ (self.uid, self.accession_number, self.patient_name, self.body_part, self.status) def get_patient_location(self): if self.location is not None: return self.location else: def generate_patient_location(): if self.patient_name: return patientLocations[int(string2hash(self.patient_name)) % len(patientLocations)] else: return patientLocations[0] return generate_patient_location() def to_json_dict(self): dt = self.format_study_datetime() # calculate AI Findings column ai_findings = self.calc_ai_findings() return { 'uid': self.uid, 'accessionNumber': self.accession_number, 'patientName': self.patient_name, 'patientId': self.patient_id if self.patient_id else '-', 'patientLocation': self.get_patient_location(), 'studyTime': dt, 'bodyPart': self.body_part, 'status': self.status, 'massiveBleeding': self.massive_bleeding, 'favorite': self.favorite, 'finalized_as': self.finalized_as if self.finalized_as else '', 'analyzed_by_aidoc': True if self.analyzed_by_aidoc is None else self.analyzed_by_aidoc, 'ai_findings': ai_findings, 'order_by': self.order_by } def calc_ai_findings(self): ai_findings_set = set() for f in self.findings: ai_findings_set.add(f.label) if len(ai_findings_set) < 3: return ', '.join(ai_findings_set) else: return 'Multi-Trauma' def format_study_datetime(self): if self.study_date and self.study_time: try: # handle milliseconds study_time = self.study_time[0:6] dt = datetime.strptime(self.study_date + study_time, '%Y%m%d%H%M%S') dt = dt.strftime(current_app.config.get('DATETIME_FORMAT')) except Exception: dt = '-' else: dt = '-' return dt