Ejemplo n.º 1
0
def UpdateSourceMaterials(instance, event):
    """Update remaining material for anything that was used in the solution
    """
    mu = instance.materials_used
    if mu:
        for x in mu:  # {'material title (key)':'mass/volume'(value),}
            brains = find(object_provides=IMaterial.__identifier__, Title=x)
            if brains:
                material = brains[0].getObject()
                temp = Decimal(material.remaining_amount) - Decimal(mu[x])
                material.remaining_amount = float(temp)
            else:
                logger.warn(
                    "%s: Update source materials: material not found: %s" %
                    (instance, x))

    su = instance.solutions_used
    if su:
        for x in su:  # {'solution title (key)':'mass/volume'(value),}
            brains = find(object_provides=ISolution.__identifier__, Title=x)
            if brains:
                solution = brains[0].getObject()
                temp = Decimal(solution.remaining_amount) - Decimal(su[x])
                solution.remaining_amount = float(temp)
            else:
                logger.warn(
                    "%s: Update source materials: solution not found: %s" %
                    (instance, x))
Ejemplo n.º 2
0
def UpdateSourceMaterials(instance, event):
    """Update remaining material for anything that was used in the solution
    """
    mu = instance.materials_used
    if mu:
        for x in mu:  # {'material title (key)':'mass/volume'(value),}
            brains = find(object_provides=IMaterial.__identifier__, Title=x)
            if brains:
                material = brains[0].getObject()
                temp = Decimal(material.remaining_amount) - Decimal(mu[x])
                material.remaining_amount = float(temp)
            else:
                logger.warn(
                    "%s: Update source materials: material not found: %s" %
                    (instance, x))

    su = instance.solutions_used
    if su:
        for x in su:  # {'solution title (key)':'mass/volume'(value),}
            brains = find(object_provides=ISolution.__identifier__, Title=x)
            if brains:
                solution = brains[0].getObject()
                temp = Decimal(solution.remaining_amount) - Decimal(su[x])
                solution.remaining_amount = float(temp)
            else:
                logger.warn(
                    "%s: Update source materials: solution not found: %s" %
                    (instance, x))
 def get_aliquot_from_fn(self, fn):
     sample_id = fn.split('_')[0]
     brains = find(object_provides=ISample.__identifier__, id=sample_id)
     if not brains:
         msg = "%s: Can't find sample '%s'" % (fn, sample_id)
         raise RuntimeError(msg)
     sample = brains[0].getObject()
     # run through the plates, till we find one containing an aliquot
     # which is a child of this sample:
     aliquot = None
     for plate in self.run.plates:
         for key, value in plate.items():
             try:
                 obj = find(UID=value)[0].getObject()
             except IndexError:
                 continue
             if obj.aq_parent.aq_parent == sample:
                 aliquot = obj
                 break
         if aliquot:
             break
     else:
         msg = "Aliquot not found for file: %s" % fn
         raise RuntimeError(msg)
     return aliquot
Ejemplo n.º 4
0
    def get_assay_solutions(self):
        """Dynamically return a list of possible batches, for each type of
        solution required by the assay
        """
        vocabs = []
        assay = self.get_assay()
        if not assay:
            return vocabs
        if assay.needed_solutions:
            for solution_type_name in assay.needed_solutions:
                type_batches = find(Type=solution_type_name,
                                    expires={
                                        'query': datetime.today().date(),
                                        'range': 'min'
                                    },
                                    sort_on='expires')

                tmp = []
                for batch in type_batches:
                    tmp.append([
                        batch.id, batch.Title,
                        batch.expires.strftime('%Y-%m-%d')
                    ])
                vocabs.append([solution_type_name, tmp])
        return vocabs
Ejemplo n.º 5
0
 def get_assay(self):
     assay_name = self.assay_name
     if assay_name:
         brains = find(portal_type='iChipAssay', Title=assay_name)
         if not brains:
             raise InvalidAssaySelected(self.assay_name)
         return brains[0].getObject()
Ejemplo n.º 6
0
    def queryClinicalSamples(self, assay):
        """Get all the samples that are review_state='received', and which
        contain an "AssayRequest" who's title matches the assay_name, and who
        have a review_state of (re_run or to_be_tested).
        """
        sample_data = []
        for testable_state in ['re_run', 'to_be_tested']:
            # this does get Clinical Samples keep reading jp
            brains = find(portal_type="AssayRequest",
                          Title=assay.title,
                          review_state=testable_state)
            tmp = []
            for brain in brains:
                assay_request = brain.getObject()
                sample = assay_request.aq_parent
                tmp.append({
                    'uid': sample.UID(),
                    'draw_date': sample.collection_date,
                    'test_status': get_state(assay_request),
                    'sample': sample
                })
            tmp = sorted(tmp, key=itemgetter('draw_date'))
            sample_data.extend(tmp)

        max_nr_samples = self.maxNumberOfSamplesToRun(assay)
        return sample_data[:max_nr_samples]
Ejemplo n.º 7
0
    def getiChipsForTesting(self, assay):
        """Get ALL iChips that can be used for the selected assay
        [[<iChipLotID>,[<iChip>,<iChip>,<iChip>]]]
        """
        ichips_for_assay = []

        brains = find(portal_type='iChipLot',
                      review_state='released',
                      sort_on='expires')
        if not brains:
            raise NoIchipLotsFound

        ichiplots = []
        for brain in brains:
            ichiplot = brain.getObject()
            if assay.title in ichiplot.intended_assay \
                    and int(ichiplot.frames) == int(assay.framecount):
                # commercial needs, correct assay
                # want to order the ichiplots in this list by exp date
                ichiplots.append(ichiplot)

        for ichiplot in ichiplots:
            ichips = ichiplot.objectValues()
            filtered = [ic for ic in ichips if get_state(ic) == 'released']
            ichips_for_assay.append([ichiplot, filtered])

        return ichips_for_assay
Ejemplo n.º 8
0
 def __call__(self, context):
     """Pull all Veracis IDs for R&D and QC samples and get the next one.
     """
     brains = find(portal_type=context.REQUEST.URL.split('++')[-1])
     if not brains:
         return 1
     return max([b.getObject().bottle_number for b in brains]) + 1
Ejemplo n.º 9
0
 def __call__(self, context):
     brains = find(object_provides=IQCSample.__identifier__,
                   review_state='in_use')
     items = []
     for b in brains:
         items.append(SimpleVocabulary.createTerm(b.veracis_id))
     return SimpleVocabulary(items)
Ejemplo n.º 10
0
 def __call__(self, context):
     brains = find(IProvider.__identifer__)
     values = [b.getObject() for b in brains]
     names = [" ".join([str(v.site_ID), v.first_name, v.last_name])
              for v in values]
     items = [(n, normalize(n)) for n in names]
     return SimpleVocabulary.fromItems(items)
Ejemplo n.º 11
0
 def __call__(self, context):
     brains = find(
         object_provides='immunarray.lims.interfaces.material.IMaterial',
         remaining_amount={'query': 1, 'range': 'min'},
         sort_on='sortable_title',
         **self.kwargs)
     return SimpleVocabulary.fromValues([brain.Title for brain in brains])
 def process_raw_flipped(self, path):
     """Store flipped images in ichips
     """
     flpath = join(path, 'Raw', 'Flipped')
     log = []
     for fn in os.listdir(flpath):
         if 'jpg' not in fn:
             continue
         splits = fn.lower().split('_')
         ichip_id = splits[1].replace('.', '-') + "_%03d" % int(splits[2])
         brains = find(object_provides=IiChip.__identifier__, id=ichip_id)
         if not brains:
             msg = "%s/%s: Can't find ichip '%s'" % (flpath, fn, ichip_id)
             raise RuntimeError(msg)
         ichip = brains[0].getObject()
         try:
             img = create(container=ichip, type='Image', id=fn, title=fn)
         except BadRequest as e:
             msg = "Run import has already been performed! (%s)" % e.message
             raise BadRequest(msg)
         except Unauthorized:
             msg = "Failed to create %s in ichip %s" % (fn, ichip.title)
             raise Unauthorized(msg)
         ts = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M")
         log.append(u"%s: Added image to ichip %s: %s" % (ts, ichip.id, img))
     return log
Ejemplo n.º 13
0
 def get_assay(self):
     assay_name = self.assay_name
     if assay_name:
         brains = find(portal_type='iChipAssay', Title=assay_name)
         if not brains:
             raise InvalidAssaySelected(self.assay_name)
         return brains[0].getObject()
Ejemplo n.º 14
0
    def getiChipsForTesting(self, assay):
        """Get ALL iChips that can be used for the selected assay
        [[<iChipLotID>,[<iChip>,<iChip>,<iChip>]]]
        """
        ichips_for_assay = []

        brains = find(portal_type='iChipLot',
                      review_state='released',
                      sort_on='expires')
        if not brains:
            raise NoIchipLotsFound

        ichiplots = []
        for brain in brains:
            ichiplot = brain.getObject()
            if assay.title in ichiplot.intended_assay \
                    and int(ichiplot.frames) == int(assay.framecount):
                # commercial needs, correct assay
                # want to order the ichiplots in this list by exp date
                ichiplots.append(ichiplot)

        for ichiplot in ichiplots:
            ichips = ichiplot.objectValues()
            filtered = [ic for ic in ichips if get_state(ic) == 'released']
            ichips_for_assay.append([ichiplot, filtered])

        return ichips_for_assay
Ejemplo n.º 15
0
def get_sequence_start(veracis_id):
    """Discover the next available aliquot number for the sample with
    the provided veracis_id.
    """
    brains = find(object_provides=[IQCAliquot.__identifier__,
                                   IRandDAliquot.__identifier__],
                  veracis_id=veracis_id)
    return len(brains) + 1
Ejemplo n.º 16
0
 def __call__(self, context):
     values = find(object_provides=IQCSample.__identifier__)
     qcsample_ids = [v.UID for v in values]
     items = []
     for uid in qcsample_ids:
         a = get(UID=uid)
         items.append(SimpleVocabulary.createTerm(a.veracis_id))
     return SimpleVocabulary(items)
 def get_aliquots(self, *interfaces):
     items = set()
     for plate in self.run.plates:
         for key, val in plate.items():
             brains = find(object_provides=interfaces, UID=val)
             if brains:
                 items.add(brains[0].getObject())
     return items
Ejemplo n.º 18
0
def _get_navigation_root(context):
    """Find the correct navigation root."""
    documents = content.find(portal_type='Document', id='front-page')
    if len(documents) == 0:
        return portal.get()
    front_page = documents[0].getObject()

    return portal.get_navigation_root(front_page)
Ejemplo n.º 19
0
    def save_run(self):
        """Create initial run
        """

        values = get_serializeArray_form_values(self.request)

        try:
            assay = find(object_provides=IiChipAssay.__identifier__,
                         Title=values['assay_name'])[0].getObject()
        except IndexError:
            raise InvalidAssaySelected(values['assay_name'])

        plates, ichips, aliquots = self.transmogrify_inputs(values['plates'])
        plates = self.remove_empty_plates(plates)
        plates = self.reorder_plates(plates)

        solutions = [values[x] for x in values if x.startswith('solution-')]

        self.transition_plate_contents(ichips, aliquots, 'queue')
        lab_users = LabUsersUserVocabulary(self).by_value
        planner = lab_users.get(values['run_planner'], '')
        operator = lab_users.get(values['run_planner'], '')

        brain = find(object_provides=ITestRuns.__identifier__)[0]
        folder = brain.getObject()

        try:
            run_number = int(values['run_number'])
        except (ValueError, TypeError):
            raise TypeError("Run number must be a number.")

        run = create(
            folder,
            'TestRun',
            title=values['assay_name'],
            assay_name=assay.title,
            assay_uid=assay.UID(),
            run_number=run_number,
            run_date=values['run_date'],
            run_planner=planner.title if planner else '',
            run_operator=operator.title if operator else '',
            plates=plates,
            solutions=solutions
        )
        return run
Ejemplo n.º 20
0
 def framecount(self):
     """Return the framecount from the assigned ichip-assay
     """
     try:
         ia = find(UID=self.assay_uid)[0].getObject()
     except IndexError:
         msg = "Shouldn't happen, Can't resolve ichip assay for testrun."
         raise RuntimeError(msg)
     return ia.framecount if ia.framecount else 5
 def patient_from_aliquot(self, aliquot):
     brains = find(object_provides=IPatient.__identifier__)
     sample = self.get_sample_from_aliquot(aliquot)
     for brain in brains:
         patient = brain.getObject()
         if sample.usn in patient.tested_unique_sample_ids:
             return patient
     aid = aliquot.id
     raise RuntimeError("Cannot find patient linked with aliquot %s" % aid)
Ejemplo n.º 22
0
 def getQCSampleObject(self, veracis_id):
     """input veracis_id, get qc sample object
     """
     brains = find(portal_type='QCSample',
                   review_state='in_use',
                   veracis_id=veracis_id)
     if not brains:
         raise QCSampleNotFound("Veracis ID: %s" % veracis_id)
     return brains[0].getObject()
Ejemplo n.º 23
0
 def getQCSampleObject(self, veracis_id):
     """input veracis_id, get qc sample object
     """
     brains = find(portal_type='QCSample',
                   review_state='in_use',
                   veracis_id=veracis_id)
     if not brains:
         raise QCSampleNotFound("Veracis ID: %s" % veracis_id)
     return brains[0].getObject()
Ejemplo n.º 24
0
    def save_run(self):
        """Create initial run
        """

        values = get_serializeArray_form_values(self.request)

        try:
            assay = find(object_provides=IiChipAssay.__identifier__,
                         Title=values['assay_name'])[0].getObject()
        except IndexError:
            raise InvalidAssaySelected(values['assay_name'])

        plates, ichips, aliquots = self.transmogrify_inputs(values['plates'])
        plates = self.remove_empty_plates(plates)
        plates = self.reorder_plates(plates)

        solutions = [values[x] for x in values if x.startswith('solution-')]

        self.transition_plate_contents(ichips, aliquots, 'queue')
        lab_users = LabUsersUserVocabulary(self).by_value
        planner = lab_users.get(values['run_planner'], '')
        operator = lab_users.get(values['run_planner'], '')

        brain = find(object_provides=ITestRuns.__identifier__)[0]
        folder = brain.getObject()

        try:
            run_number = int(values['run_number'])
        except (ValueError, TypeError):
            raise TypeError("Run number must be a number.")

        run = create(folder,
                     'TestRun',
                     title=values['assay_name'],
                     assay_name=assay.title,
                     assay_uid=assay.UID(),
                     run_number=run_number,
                     run_date=values['run_date'],
                     run_planner=planner.title if planner else '',
                     run_operator=operator.title if operator else '',
                     plates=plates,
                     solutions=solutions)
        return run
Ejemplo n.º 25
0
 def __call__(self, context):
     """Pull all Veracis IDs for R&D and QC samples and get the next one.
     """
     brains = find(portal_type=['QCSample', 'RandDSample'],
                   sort_on='veracis_id',
                   sort_order='reverse', limit=1)
     if brains:
         _id = str(int(brains[0].veracis_id) + 1)
         return unicode(_id)
     logger.info("assignVeracisId: No QC or RandD samples: using ID '1000'")
     return u"1000"
 def provider_from_aliquot(self, aliquot):
     sample = self.get_sample_from_aliquot(aliquot)
     provider_name = sample.sample_ordering_healthcare_provider
     brains = find(object_provides=IProvider.__identifier__, Title=provider_name)
     if len(brains) > 1:
         raise RuntimeError("Found more than one provider with title='%s'" % provider_name)
     try:
         provider = brains[0].getObject()
     except IndexError:
         raise RuntimeError("Provider not found matching title='%s'" % provider_name)
     return provider
Ejemplo n.º 27
0
 def update_kit_count(self, site_id):
     """Update site kits on hand count to be reduced by 1
     """
     site_objects = find(portal_type='Site')
     for i in site_objects:
         if i.Title == site_id:
             uid = i.UID
             site = api.content.get(UID=uid)
             site.kits_on_site -= 1
             # Account for free kits, so that number counts down
             if site.free_kits_left > 0:
                 site.free_kits_left -= 1
Ejemplo n.º 28
0
    def __call__(self, context):
        wells = ["-A", "-B", "-C", "-D", "-E", "-F", "-H"]
        values = find(portal_type='iChip')
        ichips = [v.Title for v in values]
        unique_ichip_wells = []
        for o in ichips:
            for w in wells:
                well_location = o + w
                unique_ichip_wells.append(well_location)

        items = [(i, normalize(i)) for i in unique_ichip_wells]
        return SimpleVocabulary.fromItems(items)
Ejemplo n.º 29
0
 def update_kit_count(self, site_id):
     """Update site kits on hand count to be reduced by 1
     """
     site_objects = find(portal_type='Site')
     for i in site_objects:
         if i.Title == site_id:
             uid = i.UID
             site = api.content.get(UID=uid)
             site.kits_on_site -= 1
             # Account for free kits, so that number counts down
             if site.free_kits_left > 0:
                 site.free_kits_left -= 1
Ejemplo n.º 30
0
    def __call__(self, context):
        wells = ["-A", "-B", "-C", "-D", "-E", "-F", "-H"]
        values = find(portal_type='iChip')
        ichips = [v.Title for v in values]
        unique_ichip_wells = []
        for o in ichips:
            for w in wells:
                well_location = o + w
                unique_ichip_wells.append(well_location)

        items = [(i, normalize(i)) for i in unique_ichip_wells]
        return SimpleVocabulary.fromItems(items)
Ejemplo n.º 31
0
 def __call__(self, context):
     """Pull all box numbers and get the next one.
     """
     brains = find(portal_type=['CommercialBox', 'RandDBox', 'QCBox'],
                   sort_on='box_number',
                   sort_order='reverse',
                   limit=1)
     if brains:
         _id = str(int(brains[0].box_number) + 1)
         return unicode(_id)
     logger.info("assignBoxNumber: No Boxes Exist: using ID '1'")
     return u"1"
Ejemplo n.º 32
0
 def __call__(self, context):
     """Pull all Veracis IDs for R&D and QC samples and get the next one.
     """
     brains = find(portal_type=['QCSample', 'RandDSample'],
                   sort_on='veracis_id',
                   sort_order='reverse',
                   limit=1)
     if brains:
         _id = str(int(brains[0].veracis_id) + 1)
         return unicode(_id)
     logger.info("assignVeracisId: No QC or RandD samples: using ID '1000'")
     return u"1000"
Ejemplo n.º 33
0
 def collectAliquots(self, sample_object, **kwargs):
     """Get in array of objects to see if they are the last in the chain
     and return a list of objects back.  Check if each is a working aliquot
     that meets the needs of the assay
 
     Type is the value of the index called 'Type'.  It's set (for aliquots)
     in the adapters/indexers.py.
     """
     path = '/'.join(sample_object.getPhysicalPath())
     brains = find(path={'query': path, 'depth': -1},
                   sort_on='id',
                   **kwargs)
     items = [b.getObject() for b in brains]
     return items
Ejemplo n.º 34
0
    def transmogrify_inputs(self, plates):
        """Convert titles to UIDs for all ichips and aliquots
        """
        ichips, aliquots = [], []
        # A single plate run must be converted to a list of plates
        if isinstance(plates, dict):
            plates = [plates]
        for plate in plates:
            for chip_nr in range(1, 5):
                for well_nr in range(1, 9):
                    key = "chip-{}_well-{}".format(chip_nr, well_nr)
                    if plate.get(key, False):
                        brains = find(object_provides=IAliquot.__identifier__,
                                      Title=plate[key])
                        plate[key] = brains[0].UID
                        aliquots.append(brains[0].getObject())
                key = "chip-id-{}".format(chip_nr)
                if plate.get(key, False):
                    brains = find(object_provides=IiChip.__identifier__,
                                  Title=plate[key])
                    plate[key] = brains[0].UID
                    ichips.append(brains[0].getObject())

        return plates, ichips, aliquots
Ejemplo n.º 35
0
    def transmogrify_inputs(self, plates):
        """Convert titles to UIDs for all ichips and aliquots
        """
        ichips, aliquots = [], []
        # A single plate run must be converted to a list of plates
        if isinstance(plates, dict):
            plates = [plates]
        for plate in plates:
            for chip_nr in range(1, 5):
                for well_nr in range(1, 9):
                    key = "chip-{}_well-{}".format(chip_nr, well_nr)
                    if plate.get(key, False):
                        brains = find(object_provides=IAliquot.__identifier__,
                                      Title=plate[key])
                        plate[key] = brains[0].UID
                        aliquots.append(brains[0].getObject())
                key = "chip-id-{}".format(chip_nr)
                if plate.get(key, False):
                    brains = find(object_provides=IiChip.__identifier__,
                                  Title=plate[key])
                    plate[key] = brains[0].UID
                    ichips.append(brains[0].getObject())

        return plates, ichips, aliquots
Ejemplo n.º 36
0
 def collectAliquots(self, sample_object, **kwargs):
     """Get in array of objects to see if they are the last in the chain
     and return a list of objects back.  Check if each is a working aliquot
     that meets the needs of the assay
 
     Type is the value of the index called 'Type'.  It's set (for aliquots)
     in the adapters/indexers.py.
     """
     path = '/'.join(sample_object.getPhysicalPath())
     brains = find(path={
         'query': path,
         'depth': -1
     },
                   sort_on='id',
                   **kwargs)
     items = [b.getObject() for b in brains]
     return items
    def get_run(self, path):
        run_nr = self.get_run_nr(path)
        # get the run nr so we can loop the plates
        brains = find(object_provides=IVeracisRunBase.__identifier__,
                      run_number=run_nr)
        if not brains:
            msg = "No test run found with run_number=%s." % run_nr
            raise RuntimeError(msg)
        run = brains[0].getObject()

        # verify that run is in correct state for import.
        state = get_state(run)
        if state != 'scanning':
            if state == 'resulted':
                return None
            msg = "Test run %s is in state '%s'.  Expected state: 'scanning'" \
                  % (run.title, state)
            raise RunInIncorrectState(msg)

        return run
Ejemplo n.º 38
0
    def get_assay_solutions(self):
        """Dynamically return a list of possible batches, for each type of
        solution required by the assay
        """
        vocabs = []
        assay = self.get_assay()
        if not assay:
            return vocabs
        for solution_type_name in assay.needed_solutions:
            type_batches = find(Type=solution_type_name,
                                expires={'query': datetime.today().date(),
                                         'range': 'min'},
                                sort_on='expires')

            tmp = []
            for batch in type_batches:
                tmp.append([batch.id,
                            batch.Title,
                            batch.expires.strftime('%Y-%m-%d')])
            vocabs.append([solution_type_name, tmp])
        return vocabs
Ejemplo n.º 39
0
 def store_aliquot(self, uid, usn, aliquot_type, target_box_type):
     # get active box from workflow state, if one doesn't exist make it,
     # check for aliquot space in box, if none make a new box
     aliquot_type = aliquot_type  # Bulk or Working
     target_box_type = target_box_type  # CommercialBox, RandDBox, QCBox
     # find the active box of the type we need,
     brains = find(portal_type=target_box_type, review_state='active')
     if brains is not None:
         for brain in brains:
             cb = brain.getObject()
             if cb.box_type == aliquot_type:
                 if cb.remaining_volume > 0:
                     box_to_use = cb.UID
                     entry_key = str(len(cb.aliquot.keys()) + 1)
                     entry_value = [usn, uid]  # Aliquot ID, UID
                     # thing to add it to cb.aliquot_dic
                 else:
                     # change box workflow to full
                     try:
                         transition(cb, "filled")
                     except:
                         msg = "Could not transition %s, action='filled'" % \
                               cb.Title
                         raise ObjectInInvalidState(msg)
                         # see if rack has empty space, if not bail, and
                         # alert user make a new aliquot_type, and return
                         # this UID
                     rack = cb.aq_parent
                     new_box = api.content.create(
                         container=rack,
                         type=target_box_type,
                         title="",
                         box_type=aliquot_type,
                         max_samples=81,
                         remaining_volume=80,
                         aliquot_dic={u'1', [usn, uid]})
     else:
         print "No Active Box for Parameters sent"
Ejemplo n.º 40
0
 def store_aliquot(self, uid, usn, aliquot_type, target_box_type):
     # get active box from workflow state, if one doesn't exist make it,
     # check for aliquot space in box, if none make a new box
     aliquot_type = aliquot_type  # Bulk or Working
     target_box_type = target_box_type  # CommercialBox, RandDBox, QCBox
     # find the active box of the type we need,
     brains = find(portal_type=target_box_type, review_state='active')
     if brains is not None:
         for brain in brains:
             cb = brain.getObject()
             if cb.box_type == aliquot_type:
                 if cb.remaining_volume > 0:
                     box_to_use = cb.UID
                     entry_key = str(len(cb.aliquot.keys()) + 1)
                     entry_value = [usn, uid]  # Aliquot ID, UID
                     # thing to add it to cb.aliquot_dic
                 else:
                     # change box workflow to full
                     try:
                         transition(cb, "filled")
                     except:
                         msg = "Could not transition %s, action='filled'" % \
                               cb.Title
                         raise ObjectInInvalidState(msg)
                         # see if rack has empty space, if not bail, and
                         # alert user make a new aliquot_type, and return
                         # this UID
                     rack = cb.aq_parent
                     new_box = api.content.create(
                         container=rack,
                         type=target_box_type,
                         title="",
                         box_type=aliquot_type,
                         max_samples=81,
                         remaining_volume=80,
                         aliquot_dic={u'1', [usn, uid]})
     else:
         print "No Active Box for Parameters sent"
Ejemplo n.º 41
0
def run_objects(instance):
    clinicalaliquots = []
    qcaliquots = []
    ichips = []
    assayrequests = []
    for plate in instance.plates:
        for key, value in plate.items():
            brains = find(UID=value)
            if brains:
                obj = brains[0].getObject()
            _items = qcaliquots + clinicalaliquots + ichips + assayrequests
            if not obj or obj in _items:
                continue
            if IiChip.providedBy(obj):
                ichips.append(obj)
            elif IQCAliquot.providedBy(obj):
                qcaliquots.append(obj)
            elif IClinicalAliquot.providedBy(obj):
                clinicalaliquots.append(obj)
                # get assayrequest
                ar = get_assayrequest_from_aliquot(obj)
                assayrequests.append(ar)
    return assayrequests, clinicalaliquots, ichips, qcaliquots
Ejemplo n.º 42
0
    def queryClinicalSamples(self, assay):
        """Get all the samples that are review_state='received', and which
        contain an "AssayRequest" who's title matches the assay_name, and who
        have a review_state of (re_run or to_be_tested).
        """
        sample_data = []
        for testable_state in ['re_run', 'to_be_tested']:
            # this does get Clinical Samples keep reading jp
            brains = find(portal_type="AssayRequest",
                          Title=assay.title,
                          review_state=testable_state)
            tmp = []
            for brain in brains:
                assay_request = brain.getObject()
                sample = assay_request.aq_parent
                tmp.append({'uid': sample.UID(),
                            'draw_date': sample.collection_date,
                            'test_status': get_state(assay_request),
                            'sample': sample})
            tmp = sorted(tmp, key=itemgetter('draw_date'))
            sample_data.extend(tmp)

        max_nr_samples = self.maxNumberOfSamplesToRun(assay)
        return sample_data[:max_nr_samples]
    def process_results_xlsx(self, path):
        """Take values from path/Out/Results/SLEkey_Results.xlsx, and write
        them to the database
        """
        run = self.get_run(path)

        # Get the first sheet
        filename = join(path, 'Out', 'Results', 'SLEkey_Results.xlsx')
        wb = openpyxl.load_workbook(filename)
        ws = wb.get_sheet_by_name('Sheet1')

        # header rows for blocks containg QC and Clinical aliquot/sample info
        qc_head_row = self.findnextSerial_Numberrow(ws, 1)
        clin_head_row = self.findnextSerial_Numberrow(ws, qc_head_row + 1)

        # get column letters of all qc headers that start with "ichip*"
        qc_ichip_cols = []
        passfail_col = None
        for col in all_cols:
            coord = "%s%s" % (col, qc_head_row)
            val = "%s" % ws[coord].value
            if val:
                if val.lower().startswith("fina"):
                    passfail_col = coord
                if val.lower().startswith("ichip"):
                    qc_ichip_cols.append(col)

        ichip_passfail_combos = []
        if passfail_col:
            for row in range(qc_head_row + 1, clin_head_row):
                passfail = "%s" % ws["%s%s" % (passfail_col, row)].value
                ichip_titles = []
                for col in qc_ichip_cols:
                    ichip_titles.append(ws["%s%s" % (col, row)].value)
                ichip_passfail_combos.append([ichip_titles, passfail])

        # for each plate
        for plate in run.plates:
            plate_ichips = []
            plate_ichiplot_titles = []

            # get all unique ichip lot numbers in a list
            for key, uid in plate.items():
                if key.startswith('ichip-id'):
                    ichip = find(UID=uid)[0].getObject()
                    plate_ichips.append(ichip)
                    ichiplot_title = ichip.title.upper().split('-')[0]
                    if ichiplot_title not in plate_ichiplot_titles:
                        plate_ichiplot_titles.append(ichiplot_title)
            for combo in ichip_passfail_combos:
                if sorted(plate_ichiplot_titles) == sorted(combo[0]):
                    for ichip in plate_ichips:
                        transition(ichip, 'qc_' + combo[1].lower())

            # 'consume' qc aliquots.
            for uid in plate.values():
                brains = find(object_provides=IQCAliquot.__identifier__,
                              UID=uid, review_state='in_process')
                if brains:
                    transition(brains[0].getObject(), 'done')

        # find the column at which the following headers are located:
        cols = {'Sample_ID': '',
                'SLE_key_Score': '',
                'SLE_key_Classification': '',
                'Assay_QC_Status': ''}
        if not all(cols):
            msg = "One of the column headers can't be located:" % pformat(cols)
            raise SpreadsheetParseError(msg)
        for col in all_cols:
            coord = "%s%s" % (col, clin_head_row)
            value = ws[coord].value
            if value in cols:
                cols[value] = col

        # get values from each row and colum into aliquot_results. results is:
        # {sample_id: [SLE_key_Score,
        #              SLE_key_Classification,
        #              Assay_QC_Status],}
        aliquot_results = {}
        first_empty = self.get_first_empty_row(ws, clin_head_row)
        for row in range(clin_head_row + 1, first_empty):
            sample_id = ws["%s%s" % (cols['Sample_ID'], row)].value
            score = ws["%s%s" % (cols['SLE_key_Score'], row)].value
            classif = ws["%s%s" % (cols['SLE_key_Classification'], row)].value
            status = ws["%s%s" % (cols['Assay_QC_Status'], row)].value
            aliquot_results[sample_id] = {
                'SLE_key_Score': score,
                'SLE_key_Classification': "%s" % classif,
                'Assay_QC_Status': "%s" % status
            }

        log = []

        _used_uids = []
        for plate in run.plates:
            for uid in plate.values():
                if uid in _used_uids:
                    continue
                _used_uids.append(uid)
                brains = find(UID=uid)
                if not brains:
                    continue
                aliquot = brains[0].getObject()
                if not IAliquot.providedBy(aliquot):
                    continue
                sample = self.get_sample_from_aliquot(aliquot)
                if IClinicalSample.providedBy(sample):
                    if sample.title not in aliquot_results:
                        msg = "Sample '%s' not in spreadsheet results: %s" % \
                              (sample.title, pformat(aliquot_results))
                        raise RuntimeError(msg)
                    result = aliquot_results[sample.title]
                    ar = self.get_ar_from_sample(sample, run.assay_name)
                    state = result['Assay_QC_Status'].lower()
                    ar.aliquot_evaluated = aliquot.title
                    ar.date_resulted = self.get_date(ws)
                    # assayrequest is associated with multiple aliquots,
                    # so we only transition if the AR's state is expected.
                    if get_state(ar) == 'in_process':
                        transition(ar, 'qc_' + state)
                aliquot.numeric_result = result['SLE_key_Score']
                aliquot.text_result = result['SLE_key_Classification']
                ts = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M")
                log.append("%s: Sample: %s, Aliquot: %s, Results: %s, %s" % (
                    ts,
                    sample.title,
                    aliquot.title,
                    result['SLE_key_Score'],
                    result['SLE_key_Classification'],
                ))
        return log
Ejemplo n.º 44
0
 def is_lqc(self, sample):
     assay = find(UID=self.context.assay_uid)[0].getObject()
     lqc_id = assay.qc_low_choice
     return sample.id.split('-')[0] == lqc_id
Ejemplo n.º 45
0
    def __call__(self):

        wb = self.load_workbook()
        ws = wb.get_sheet_by_name('Form')

        # A6 - add run number to 'FILE NAME'
        ws['A6'].value += ' (Veracis Test Run %s)' % self.context.run_number
        # A7 - PURPOSE
        ws['A7'].value += ' %s' % self.context.assay_name
        # A8 - DATE
        ws['A8'].value += ' %s' % self.context.run_date
        # D8 - PLANNED BY
        ws['D8'].value += ' %s' % self.context.run_planner
        # H8 - PERFORMED BY
        ws['H8'].value += ' %s' % self.context.run_operator

        # PLATE HEADERS are at 10, 27, 44, 61, 78
        for plate_nr, plate_cell in enumerate([10, 27, 44, 61, 78]):
            plate_nr += 1

            # verify plate header exists in spreadsheet
            plate_title = 'plate %s' % plate_nr
            plate_header_cell = ws['A%s' % plate_cell]
            assert plate_header_cell.value.lower() == plate_title

            # verify the plate exists in run.plates
            if len(self.context.plates) < plate_nr:
                break
            plate = self.context.plates[plate_nr - 1]

            # ALIQUOT WELL ROWS are PLATE HEADER+[2..9] in COLS B,D,F,H
            for chip_nr, chip_col in enumerate('BDFH'):
                for well_nr in range(8):
                    uid = plate['chip-%s_well-%s' % (chip_nr + 1, well_nr + 1)]
                    if uid:
                        brain = find(UID=uid)[0]
                        row = plate_cell + (well_nr + 2)
                        cell = ws['%s%s' % (chip_col, row)]
                        cell.value = brain.Title

            # +1 for ICHIP in rows C,E,G,I  -  and "COMMENTS" in J
            row = plate_cell + 10
            for chip_nr, chip_col in enumerate('CEGI'):
                uid = plate['chip-id-%s' % (chip_nr + 1)]
                if not uid:
                    raise MissingIChipForSlide("plate %s, slide %s" %
                                               (plate_nr, chip_nr + 1))
                brain = find(UID=uid)[0]
                cell = ws['%s%s' % (chip_col, row)]
                cell.value = brain.Title
                # comments in J
                cell = ws['J%s' % row]
                cell.value = plate['comments-ichip-%s' % (chip_nr + 1)]

            # +1 for ICHIP in rows C,E,G,I  -  and "COMMENTS" in J
            row = plate_cell + 10
            for chip_nr, chip_col in enumerate('CEGI'):
                uid = plate['chip-id-%s' % (chip_nr + 1)]
                if not uid:
                    raise MissingIChipForSlide("plate %s, slide %s" %
                                               (plate_nr, chip_nr + 1))
                brain = find(UID=uid)[0]
                cell = ws['%s%s' % (chip_col, row)]
                cell.value = brain.Title
                # comments in J
                cell = ws['J%s' % row]
                cell.value = plate['comments-ichip-%s' % (chip_nr + 1)]

            # +1 for SCAN SLOT C,E,G,I
            row = plate_cell + 11
            for chip_nr, slot_col in enumerate('CEGI'):
                cell = ws['%s%s' % (slot_col, row)]
                cell.value = plate['scan-slot-%s' % (chip_nr + 1)]

            # +2 for COMMENTS in B,D,F,H
            row = plate_cell + 13
            for chip_nr, comment_col in enumerate('CEGI'):
                cell = ws['%s%s' % (comment_col, row)]
                cell.value = plate['comments-ichip-%s' % (chip_nr + 1)]

        fn = "{}-{}".format(self.context.assay_name, self.context.run_number)
        fn = normalize(fn) + ".xlsx"

        setheader = self.request.RESPONSE.setHeader
        setheader('Content-Type', 'application/vnd.ms-excel')
        setheader("Content-Disposition", 'attachment;filename="%s"' % fn)

        fn = tempfile.mktemp()
        wb.save(fn)
        data = open(fn).read()

        self.request.RESPONSE.write(data)
Ejemplo n.º 46
0
 def is_lqc(self, sample):
     assay = find(UID=self.context.assay_uid)[0].getObject()
     lqc_id = assay.qc_low_choice
     return sample.id.split('-')[0] == lqc_id
Ejemplo n.º 47
0
    def __call__(self):

        wb = self.load_workbook()
        ws = wb.get_sheet_by_name('Form')

        # A6 - add run number to 'FILE NAME'
        ws['A6'].value += ' (Veracis Test Run %s)' % self.context.run_number
        # A7 - PURPOSE
        ws['A7'].value += ' %s' % self.context.assay_name
        # A8 - DATE
        ws['A8'].value += ' %s' % self.context.run_date
        # D8 - PLANNED BY
        ws['D8'].value += ' %s' % self.context.run_planner
        # H8 - PERFORMED BY
        ws['H8'].value += ' %s' % self.context.run_operator

        # PLATE HEADERS are at 10, 27, 44, 61, 78
        for plate_nr, plate_cell in enumerate([10, 27, 44, 61, 78]):
            plate_nr += 1

            # verify plate header exists in spreadsheet
            plate_title = 'plate %s' % plate_nr
            plate_header_cell = ws['A%s' % plate_cell]
            assert plate_header_cell.value.lower() == plate_title

            # verify the plate exists in run.plates
            if len(self.context.plates) < plate_nr:
                break
            plate = self.context.plates[plate_nr - 1]

            # ALIQUOT WELL ROWS are PLATE HEADER+[2..9] in COLS B,D,F,H
            for chip_nr, chip_col in enumerate('BDFH'):
                for well_nr in range(8):
                    uid = plate['chip-%s_well-%s' % (chip_nr + 1, well_nr + 1)]
                    if uid:
                        brain = find(UID=uid)[0]
                        row = plate_cell + (well_nr + 2)
                        cell = ws['%s%s' % (chip_col, row)]
                        cell.value = brain.Title

            # +1 for ICHIP in rows C,E,G,I  -  and "COMMENTS" in J
            row = plate_cell + 10
            for chip_nr, chip_col in enumerate('CEGI'):
                uid = plate['chip-id-%s' % (chip_nr + 1)]
                if not uid:
                    raise MissingIChipForSlide(
                        "plate %s, slide %s" % (plate_nr, chip_nr + 1))
                brain = find(UID=uid)[0]
                cell = ws['%s%s' % (chip_col, row)]
                cell.value = brain.Title
                # comments in J
                cell = ws['J%s' % row]
                cell.value = plate['comments-ichip-%s' % (chip_nr + 1)]

            # +1 for ICHIP in rows C,E,G,I  -  and "COMMENTS" in J
            row = plate_cell + 10
            for chip_nr, chip_col in enumerate('CEGI'):
                uid = plate['chip-id-%s' % (chip_nr + 1)]
                if not uid:
                    raise MissingIChipForSlide(
                        "plate %s, slide %s" % (plate_nr, chip_nr + 1))
                brain = find(UID=uid)[0]
                cell = ws['%s%s' % (chip_col, row)]
                cell.value = brain.Title
                # comments in J
                cell = ws['J%s' % row]
                cell.value = plate['comments-ichip-%s' % (chip_nr + 1)]

            # +1 for SCAN SLOT C,E,G,I
            row = plate_cell + 11
            for chip_nr, slot_col in enumerate('CEGI'):
                cell = ws['%s%s' % (slot_col, row)]
                cell.value = plate['scan-slot-%s' % (chip_nr + 1)]

            # +2 for COMMENTS in B,D,F,H
            row = plate_cell + 13
            for chip_nr, comment_col in enumerate('CEGI'):
                cell = ws['%s%s' % (comment_col, row)]
                cell.value = plate['comments-ichip-%s' % (chip_nr + 1)]

        fn = "{}-{}".format(self.context.assay_name, self.context.run_number)
        fn = normalize(fn) + ".xlsx"

        setheader = self.request.RESPONSE.setHeader
        setheader('Content-Type', 'application/vnd.ms-excel')
        setheader("Content-Disposition", 'attachment;filename="%s"' % fn)

        fn = tempfile.mktemp()
        wb.save(fn)
        data = open(fn).read()

        self.request.RESPONSE.write(data)